这几天,在搞 ShardingSphere,这不又来了一个问题嘛,启动的时候报了一个 NPE 进去。
好在,这个问题不影响应用,只是启动会报点错,接下来,又是辛苦的排查过程。间接定位到报错的中央,发现是 ShardingSphere 在启动时候去加载表一些元数据信息报错,看到这个中央就很显著的猜想是 map 去 get 的时候报错了。
一通往上翻源码,发现这里定义的是 TreeMap,那应该没故障了,就是下面 dataType 是个 null,所以报错了,可是我还是年老了。
问题起因下面咱们曾经定位到问题呈现的中央,接下来就剖析下为什么会呈现这个问题呢?从源码看到,次要是在这个中央去加载数据库表的列的元数据信息。
在这个类里发现了拼接的 SQL 查问语句,次要是去查 information_schema 上面的 columns 表。
这时候我想看下这个到底是为啥,于是关上本地 debug 看了一下没有任何问题,而后去测试环境上发现也没有问题,如同只有生产有这个问题。这个 dataTypeMap 就是列类型的一个映射,然而本地没有方法重现。
本地没有方法的话,那就依据下面的 SQL 去生产库里看了下 COLUMNS 表这个字段有啥问题,查问一看,发现了一大堆的 null,还有一些其余的乌七八糟的类型,那看来 NPE 的起因就是因为这些 null 了。
那这些 null 值是怎么来的呢?依据排查发现都是来自 TIDB 的视图生成的。本地和测试没有方法重现是因为其实用的是 Mysql。
排查这个环境问题还挺恶心的,因为没有 TIDB 的环境,只能本人装一个了去想方法重现一下了(过程很费时间)。好在 Mac 装这些货色还是很不便的,装置、刷新环境变量、启动。1. curl –proto ‘=https’ –tlsv1.2 -sSf https://tiup-mirrors.pingcap…. | sh 2. source ${your_shell_profile} 3. tiup playground 而后本地依照那个很沙雕的创立视图的办法创立个视图进去,再本地 DEBUG 看看。进来一看,和开始想的不一样,竟然是个 null 字符串,不是我设想中的 null,那这个看起来不应该会报空指针才对啊?!
有点想不通为啥这里会空,而后关上这个类看了一眼。嗯???这尼玛???????难道是拆箱导致的?
好吧,没错。dataTypeMap.get(dataType) 是 null,拆箱调用的啥我不用说了吧,就是这起因。。。修复你说咋改?有同学说了,那还不简略,你是个沙雕吗?改成 Integer 不就完事儿了。嗯,你说的没错,我就这么改了。而后,改完之后启动又是一堆报错,到处存在调用。这玩意儿不能动,他好像在和我说,你动动试试,果然动动就去世。
文章写到这里,我还没想好怎么改,大略有 3 个计划:齐全去掉 TIDB 还用视图这离谱的操作,从本源上解决问题依照这个办法,改成 Integer,就是不晓得要改多少中央不去加载视图的元数据,就能够防止这个问题了,毕竟这年头谁用视图啊给大家个机会,去给他们提个 PR。