Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ShardingSphere分库分表schema名称导致NPE问题排查记录

ShardingSphere分库分表schema名称导致NPE问题排查记录

作者头像
艾小仙
发布于 2023-02-24 13:35:28
发布于 2023-02-24 13:35:28
93000
代码可运行
举报
文章被收录于专栏:艾小仙艾小仙
运行总次数:0
代码可运行

前段时间把 ShardingSphere 升级到了 5.1.1 版本,奈何官方版本升级太快跟不上速度,这不最近又发现了一个 BUG。

问题现象

数据库做了分库分表,在需要查询多表数据进行 merge 的时候发生了一个 NPE 的异常。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Caused by: java.lang.NullPointerException
    at org.apache.shardingsphere.sharding.merge.dql.orderby.OrderByValue.getOrderValuesCaseSensitiveFromTables(OrderByValue.java:73) ~[shardingsphere-sharding-core-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.sharding.merge.dql.orderby.OrderByValue.getOrderValuesCaseSensitive(OrderByValue.java:64) ~[shardingsphere-sharding-core-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.sharding.merge.dql.orderby.OrderByValue.<init>(OrderByValue.java:58) ~[shardingsphere-sharding-core-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.sharding.merge.dql.orderby.OrderByStreamMergedResult.orderResultSetsToQueue(OrderByStreamMergedResult.java:56) ~[shardingsphere-sharding-core-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.sharding.merge.dql.orderby.OrderByStreamMergedResult.<init>(OrderByStreamMergedResult.java:50) ~[shardingsphere-sharding-core-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.sharding.merge.dql.ShardingDQLResultMerger.build(ShardingDQLResultMerger.java:89) ~[shardingsphere-sharding-core-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.sharding.merge.dql.ShardingDQLResultMerger.merge(ShardingDQLResultMerger.java:63) ~[shardingsphere-sharding-core-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.infra.merge.MergeEngine.executeMerge(MergeEngine.java:90) ~[shardingsphere-infra-merge-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.infra.merge.MergeEngine.merge(MergeEngine.java:80) ~[shardingsphere-infra-merge-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement.mergeQuery(ShardingSpherePreparedStatement.java:487) ~[shardingsphere-jdbc-core-5.1.1.jar:5.1.1]
    at org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement.getResultSet(ShardingSpherePreparedStatement.java:435) ~[shardingsphere-jdbc-core-5.1.1.jar:5.1.1]
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getFirstResultSet(DefaultResultSetHandler.java:237) ~[mybatis-3.5.3.jar:3.5.3]
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:187) ~[mybatis-3.5.3.jar:3.5.3]
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65) ~[mybatis-3.5.3.jar:3.5.3]
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79) ~[mybatis-3.5.3.jar:3.5.3]
    at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63) ~[mybatis-3.5.3.jar:3.5.3]
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324) ~[mybatis-3.5.3.jar:3.5.3]
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156) ~[mybatis-3.5.3.jar:3.5.3]
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109) ~[mybatis-3.5.3.jar:3.5.3]
    at jdk.internal.reflect.GeneratedMethodAccessor346.invoke(Unknown Source) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63) ~[mybatis-3.5.3.jar:3.5.3]
    at com.sun.proxy.$Proxy410.query(Unknown Source) ~[?:?]
    at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:108) ~[pagehelper-5.1.11.jar:?]
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) ~[mybatis-3.5.3.jar:3.5.3]
    at com.sun.proxy.$Proxy410.query(Unknown Source) ~[?:?]
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) ~[mybatis-3.5.3.jar:3.5.3]
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140) ~[mybatis-3.5.3.jar:3.5.3]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427) ~[mybatis-spring-2.0.6.jar:2.0.6]
    ... 95 more

问题排查

跟踪到报错的地方,发现是这个地方的schema是个null,从而引发了 NPE。

一路往上看代码,最终定位到了这个获取schema的地方,也就是元数据去getDefaultSchema获取默认的schema名称改的时候拿到了一个空值。

进入这个方法后发现通过schemaschemas这个map里获取名称的时候是个空值,debug到这个地方其实发现了问题。

我们的schemaName配置的是orderTrade包含有大写字符的,所以name传进来的是orderTrade,但是问题是这个schemas确是ordertrade

所以很显然,这里获取不到正确的schema名称,导致了这个 NPE 的异常,那么问题是这个schemas是怎么加载进来的呢?

我们发现schemas是在创建元数据的时候,通过构造函数赋值的,那么只要找到这个赋值的地方应该就能发现问题了。

通过一番查找,找到了调用的地方,这个schemas值就是databaseMap中的value,那么我们要继续看这个databaseMap是如何初始化来的。

继续看源码,找到了databaseMap进行初始化的地方,原来是通过DatabaseLoader去加载元数据的时候初始化的,那么这个load方法是怎么处理的呢?

从代码来看他包含了两部分的信息,第一个是我们自己通过schema配置的一些分库分表的配置信息,另外一部分则是数据库默认的一些表的元数据,比如mysqlinformation_schema这些,那我们只要看自己配置的那部分就可以了,也就是SchemaLoader.load(dataSourceMap, rules, props)方法。

看他实际上就是获取数据库是什么类型,比如mysql,然后去加载表的元数据,最后new出来ShardingSphereSchema,直接看最后的new部分代码就行了。

进入这个方法,瞬间就真相大白了,原来在put的时候对所有的schemaName进行了小写处理,所以在最上面我们去get的时候肯定会拿到一个空值,最终导致merge的时候发生了 NPE 异常。

解决方案

现在问题原因已经发现了,那么该如何解决呢?总不能不让别人配置的时候不让写大写吧,本着能不能白嫖一个 PR 的想法,又去给 Sharding 提了一个 Issue。

就我点了根烟的功夫,回头就给我回复说新版本已经修复了,希望落空了,修复方案就是查询的时候也做小写处理了,好吧,那就这样吧。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 艾小仙 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一条SQL引发的惨案!已解决!
这本是昨天的异常,后来没腾出时间记录下来,本就是一条平平常常的SQL,同事遇到的bug,最后解决也算精彩。
疯狂的KK
2019/08/16
6940
一条SQL引发的惨案!已解决!
都说了能不动就别动,非要去调整,出生产事故了吧 → 补充
都说了能不动就别动,非要去调整,出生产事故了吧 中有一个地方讲的有瑕疵,不知道你们发现了没有
青石路
2024/02/27
2550
都说了能不动就别动,非要去调整,出生产事故了吧 → 补充
一次线上MySQL死锁告警原因排查
项目场景:一次线上MySQL死锁告警原因排查 最近处理了一次线上数据告警,记录一下。
河岸飞流
2022/05/10
1.8K0
一次线上MySQL死锁告警原因排查
java.lang.NoSuchMethodError: org.apache.log4j.Logger.isTraceEnabled()Z
原因是我的 log4j 是最低版本的 1.2.4,解决办法就是升级到 1.2.12+ 的版本。
wsuo
2020/07/31
2.8K0
java.lang.NoSuchMethodError: org.apache.log4j.Logger.isTraceEnabled()Z
Tried to send an out-of-range integer as a 2-byte value
Cause: org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
二锅头一桶天下
2024/06/26
2390
BadSqlGrammarException:PageHelper use near 'LIMIT 50'
作为一名Java开发人员,你可能在某个深夜,面对着那令人头秃的错误日志,不禁发问:“为什么我的SQL语句总是出错?”今天,就让我们一起深入探讨这个在Java开发项目中常见的问题——org.springframework.jdbc.BadSqlGrammarException,特别是在处理Excel导入时,如何避免这个让人头疼的错误。
疯狂的KK
2025/01/16
1350
BadSqlGrammarException:PageHelper use near 'LIMIT 50'
都说了能不动就别动,非要去调整,出生产事故了吧
  一个老项目,数据库用的是 MySQL 5.7.36 , ORM 框架用的 MyBatis 3.5.0 , mysql-connector-java 版本是 5.1.26
青石路
2024/02/24
1660
都说了能不动就别动,非要去调整,出生产事故了吧
公司新来一个干练小伙,把 MyBatis 替换成 MyBatis-Plus,上线后哭晕在厕所。。。
一个老项目,数据库用的是 MySQL 5.7.36 , ORM 框架用的 MyBatis 3.5.0 , mysql-connector-java 版本是 5.1.26
搜云库技术团队
2024/05/11
2220
公司新来一个干练小伙,把 MyBatis 替换成 MyBatis-Plus,上线后哭晕在厕所。。。
【Java调优】MysqlIO.readFully问题排查分析过程
支付清结算系统"外部对账"部分任务在早上6:00~7:00时间段内对账速度缓慢,且经常造成对账统计结果不准确问题,导致结转记账不准确。
用户5927304
2019/07/31
3.7K0
Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x8E\xB1' for
最近在做关于社交项目时,有一个发红包功能,其中涉及到红包描述,一直报错,后来看日志,才发现竟是因为输入了Emoji表情的原因,由于我的mysql数据库是utf8字符集,而且Emoji表情等特殊符号要占四个字节,所以导致数据库不能正常存入。
一诺千金
2020/04/30
1.6K0
HikariPool-1 - Exception during pool initialization. Springboot 默认选择的mysql问题
samRsa
2025/02/24
2080
性能调优之mysql线程池优化
对Nginx域名转发做了个压测,结果不大理想,jmeter哗哗的报错,nginx连接全是超时,tps波动特别大。如下图
飞天小子
2021/09/26
1.7K0
性能调优之mysql线程池优化
解析SQLSyntaxErrorException异常:not in GROUP BY clause
大家好,欢迎阅读我们的文章。今天,我们将讨论一个常见的Java异常——java.sql.SQLSyntaxErrorException,并深入探讨其中一个具体的错误信息:Expression #1 of SELECT list is not in GROUP BY clause。
修己xj
2023/08/25
6040
解析SQLSyntaxErrorException异常:not in GROUP BY clause
HTTP Status 500 - Request processing failed; nested exception is org.springframework.jdbc.BadSqlGram
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xmt1139057136/article/details/88684939
业余草
2019/04/09
6.3K0
HTTP Status 500 - Request processing failed; nested exception is org.springframework.jdbc.BadSqlGram
springboot整合mybatis报错
运行测试时报错如下 CLIENT_PLUGIN_AUTH is required
暴躁的程序猿
2022/03/23
3150
java.sql.SQLException: sql injection violation, multi-statement not allow
3、原因 需要设置过滤器 WallFilter 的配置: WallConfig 的参数 multiStatementAllow 为true,默认情况下false不允许批量操作
知识浅谈
2021/05/10
4.7K0
java.sql.SQLException: connection holder is null
java.sql.SQLException: connection holder is null
一个会写诗的程序员
2018/08/17
2.1K0
In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'c
数据库查询时,出现如下错误: Caused by: com.mysql.jdbc.exceptions.jdbc4MySQLSyntaxErrorException: In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'credit_server.credit.id'; this is incompatible with sql_mode=only_full_gro
IT云清
2019/03/19
17.6K2
In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'c
十二、Hikari:Apparent connection leak detected连接泄露分析
leak-detection-threshold:用来设置连接被占用的超时时间,单位为毫秒,默认为0,表示禁用连接泄露检测。
用户1422411
2022/06/25
3.2K0
一次org.springframework.jdbc.BadSqlGrammarException ### Error querying database Cause: com.mysql.jdbc.
因为在表设计中有一个商品描述字段被设置为desc,但desc是mysql中的关键字,如select id,name,desc,price from product;这条sql语句在查询时的sql语句解析会和期望的不一样,导致出现问题。因为平时在写java代码的时候很自然的会将描述变量设置为desc,在设计表字段时也没有多想,忘记和忽略了desc为mysql中的关键字,酿成此问题。
翎野君
2023/05/12
6900
推荐阅读
相关推荐
一条SQL引发的惨案!已解决!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验