案例分析"assertion failed"
由于对一些报错信息的不熟悉,导致分析过程有点曲折,也作为一个案例分享给大家。
一、故障现象
客户人员反馈程序报错, 发过来的业务日志是:
上面信息太简短, 让提取完整的 java 日志报错 call stack, 得到如下日志:
看到真实的报错原因是assertion failed
, 也给了 key 的值。
二、初次判断失误
如果熟悉assertion failed
的含义, 或是 tidb 把错误信息写得更明白一些, 那基本能猜到原因了。
但这里作者判断失误了: “可能是表中某个 key 已经存在, 业务代码想 insert, 发生了主键冲突”。
沿着上面这个思路排查:
(1) 首先查 key 的信息
有了table_id=506738
, 有 index 对象编号, 一般index_id=1
是表的主键, 也就是PK=1298949138
的记录有冲突。
(2) 查看相关表的信息
(3) 查看 PK 的信息
select * from gen_mdl where id=1298949138
没有记录。
到这里觉得事情很诡异, 一是表中没有查到这条记录, 二是如果insert
导致auto_increment
自动分配 id, 而当前表的auto id
值已经远大于 1298949138, 好象不可能。
在 tidb 日志中找到如下的日志, 与 java 的报错相对应。
由于报错没有提示是哪个 sql 引发错误(这个判断也是错的),所以让客户查一下insert gen_mdl
相关的程序代码,客户回复说相关 insert 语句看着都正常。
到这里排查陷入僵局。
三、分析的转机
几小时后,客户找过来说,他对相关事务代码中每行 DML 语句进行逐一提交, 找到了报错的 sql, 是一个delete gen_mdl where xxx
语句。
delete 语句也报主键冲突?然后隐约猜到了, 报错中assertion failed
不是说主键冲突,而是这个键值有问题。
查询 select * from gen_mdl where xxx
语句,发现了id=1298949138
这个记录。
前面查询 select * from gen_mdl where id=1298949138
为空,使用的是主键索引。
至此,明白了是主键索引和表数据不一致,导致的异常现象。
分别使用全表扫描统计全表数量,以及主键索引统计全表数量, 查得全表条数比主键条数多了几百万。
四、几点小结
4.1 tidb 日志有提示报错的 sql
复盘时仔细看了 tidb 日志, 发现里面明确写了是执行commit
语句时报的错 (虽然对排错没什么作用):
以前认为是 insert 相关语句的问题, 因此忽略了日志中的提示。
客记事后反馈说, 相关事务代码结构如下:
4.2 assertion failed 与 duplicate entry 的区别
主键重复, 报错是 duplicate entry
, 且会直接抛出有问题的 DML 语句,故障排查比较简单。
键值异常(比如通过某个 key 去找数据行时失败), 报错是 assertion failed
, 但它给分析增加难度的地方是,即使在悲观模式下,delete
语句在上锁时也不会发现数据不一致(可以正常对数据行上锁),而是在commit
时才会处理全部相关的表行和索引行,然后才抛出错误, 此时已经不知道是事务中哪个 DML 语句导致的。
所以前面提到,如果熟悉assertion failed
,则一开始就可以猜到是数据不一致。
4.3 表与主键不一致是怎么产生的
由于表的条数比主键多几百万,且客户曾经对表使用过lightning
物理导入,这里的判断也比较简单,就是物理导入时,重复导入了 csv 文件数据(如果没有过物理导入,则要仔细分析其它可能)。
lightning
物理导入数据有特别的地方:
lightning 把 csv 组成表的 sst 并且 ingest 到 tikv 中,基本会成功, 即表数据一定会写入;
lightning 把 csv 组成唯一索引的 sst 时,会进行唯一性检查, 不满足的数据会被剔除, 即索引数据不一定会全部写入;
比如,物理方式重复导入了某个 10 万条的 csv 文件, 则表中数据会多出 10 万条, 但是主键索引不变(因为不满足唯一性),此时 ligthning 导入日志中会有duplicated key found
, checksum mismatched remote vs local
之类报错信息,要引起重视。
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/e5024be8998f145f29597c3aa】。文章转载请联系作者。
评论