查询sql报错data inconsistency in table

【 TiDB 使用环境】生产环境
【 TiDB 版本】 v6.5
【复现路径】
select * from tx_build order by update_time limit 10

8133 - data inconsistency in table: tx_build, index: idx_build_03, index-count:10 != record-count:0
时间: 0.021s

admin check index tx_build tx_build_03

8003 - table count 4467708 != index(idx_build_03) count 4469445
时间: 0.362s

【遇到的问题:问题现象及影响】
【资源配置】
【附件:截图/日志/监控】

数据索引一致性错误 | PingCAP 文档中心

表和索引不一致了,没法处理了

删除索引。重建?可行不。
对于v6.5.0 重建索引特别的快

我也遇到了,不过我可能是跨版本还原导致的。你那边有类似操作么?
我这边报错是8223

重建索引可以,但是如果不知道导致这个问题操作是什么,下次还会出现一样的问题

有可能是online DDL 是异步导致的???你们公司购买 tidb企业服务了没?

tidb 不是开源产品吗?咋还有个社区版本和企业版本?

功能基本一样,企业版多了服务和审计功能

企业服务和企业版不一样。社区开源也可以收费啊

我们没有导入数据,就是业务数据慢慢插入

这个在官方文档看过的,所以来论坛看看有没有解决方案

是的,出现问题,就重建索引了,就是来论坛看看有没有删除索引外的其他方案,如果是大表,重建索引可能会很慢,可能超过10个小时以上,如果是这样有没有其他解决方案

告诉我您的数据量多大???

版本是不是已经升级到V6.5.0了??

是的版本已经是6.5版本,表的数据量目前不大,但是库的数据量比较大上T

数据修复官方提供了下面两个命令:admin cleanup、admin recover。

  • admin cleanup:适用于 index 数据多于 data 行数据的情况,会将多余的 index 数据删除掉
  • admin recover:适用于 data 行数据多于 index 行数据的情况,会将缺少的 index 数据填充完整。

admin cleanup

admin cleanup index [table_name][index_name];

理论上,在 delete 时,会同时删除数据和索引。但是在某些情况下可能没有删除索引 key,遗留了一个索引 key,某条 data 数据在重新写入后,同时写入了数据和索引,并且索引 key 和之前遗留的 key 对应同一个 handle id:

admin cleanup 并没有覆盖这个情况,可以通过下面的方式来确认是否有这样的情况:

select count(*) as cnt, id+1 from table_name use index(index_name) group by id+1 having cnt > 1

select count(*) as cnt, _tidb_rowid from table_name use index(index_name) group by _tidb_rowid having cnt > 1

一旦出现这个现象,需要通过重建索引来解决。

admin recover

admin recover index [table_name][index_name];
  • admin clean 和 recover 目前是单线程进行处理,单次处理的 batch size 是 20000,当前没有参数调整并发数量以及 batch size。后台的操作类似一个 table full scan ,表越大耗时会越久。

其他

某些情况下,表特别大,使用 admin cleanup 耗时会比较长。那么可以尝试使用下面的方式来跳过这个问题:

  • 数据索引不一致导致的业务报错,影响范围可控
  • 新建索引 index_new,并且新建的索引的列能够覆盖 index_old,满足索引前缀条件
    • 添加一个新的复合索引 index_new,如出现问题的 index_old 包括的列为 (col 1, col 2),新建的 index_new 为 (col1, col2)
    • 使业务能够继续使用 index_old 访问业务数据(但是在某些情况下,会因为数据索引不一致报错退出)
  • 关注 index_new 索引添加的进度,添加完毕后,可以将 index_old 删除
  • 观察相关 sql 的执行计划,是否能够命中 index_new,如果不能命中,可以使用 sql binding 固定执行计划

该方法仅适用于 admin cleanup 的情况 ,需要根据当前的业务访问情况评估是否使用。一个方向,可以参考下。

2 个赞

学习了,我也试试这个命令行不行

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。