BG
背景
研发突然发消息说,主库和从库的select count(*) where条件相同的情况下,结果不一致。
第一反应是主从同步异常了;
研发又说是主库的数据少了;
一脸黑线,不能是主库数据被删了吧。。。
复现问题
马上分别登录主从数据库,查询研发提供的sql。将研发的
SQL精简了一下:
主库

从库

问题确实存在,第一反应是主库的数据被删了?
count一下全表数据,数据量一致。
那么就是 state这个字段的值不一致导致的?
直接用 select * from table_name where 1=1 and state=2;
结果数据量和从库一致了,数据没问题,是count(*)出问题,陷入僵局了。。。
分析问题
既然数据没有丢失,暂时放心了,饭碗保住了。
问题可能出现在count(*)上
分别执行了 count(1) 和 count(id) 发现结果一样都是主库只有197条数据,从库数据完整。
接着尝试count(distinct(id))

问题很诡异,分别看一下执行计划




有问题的SQL的执行计划中Extra部分都出现了Using index for skip scan,这个是MySQL的优化器自动触发的使用了索引来执行跳跃扫描。理论上之后提高查询性能,并不会影响最终的count(*)结果。
看一下索引情况

索引建的部分字段重复了,但是也不应该影响查询结果,目前MySQL选择了第一个索引,尝试强制指定第二个索引试试。

结果是正确的,那么问题可能就是出现在索引上。
首先想到的是可以尝试重建索引,马上实施。
重建索引后,恢复正常。
解决问题
问题通过重建索引的方式解决了,但是导致这个问题的原因还是没有像明白。
表象问题解决了,底层逻辑是什么还没搞懂。
到底为什么这个索引导致了这个问题?知其然也要知其所以然
如果哪位大神知道问题所在请留言指导一下




