GC 监控一下
TiDB 是分布式 LSM 架构,你删了 50% 数据只是标记删除,物理空间、Region 分布、实际扫描范围没有真正变小。
这样试下:
执行 ALTER TABLE 表名 COMPACT; 合并数据碎片
低峰执行 ALTER TABLE 表名 RECLAIM DATASPACE; 回收空间
重新 ANALYZE TABLE
执行后查询立即恢复秒级响应。
应该是 删除大量数据后,TiDB 未及时触发 GC/Compaction
调整一下gc,然后更新一下统计信息
查下这个表相关的 Region 的Key 和 Value 的版本数量,如果和实际 count 数值差不多,说明回收已经完成了。否则,就先想办法 compact 回收掉哪些被标记的 Key。
这个操作会十分影响稳定性,建议在不繁忙的情况下,手动处理。
第一个可能是 region合并卡主
第两个可能是RocksDB Tombstone堆积
按照优先级操作:
- 先关 Merge:pd-ctl config set max-merge-region-size 0(立即生效,风险最低)
- 检查 Region 状态:确认是否有 Region 卡在 pending_merge_state
- 检查 RocksDB tombstone:如果有大量 tombstone,考虑手动 compaction
- 确认索引:如果表本身没有合适的索引,limit 1 的确会走全表扫描,但即使如此,如果所有 Region 都正常,limit 1 不应超时
应该是等待GC清理吧
region合并中间出现卡顿了吗
删除操作会产生大量的写操作和事务日志,这会增加磁盘I/O和事务日志的写入压力
大量删除操作可能会导致数据碎片化,同时索引也可能变得不完整或失效。这会影响 TiDB 的查询性能。
删除数据实际只是打上删除标记,并非物理清理,需等待 GC 周期完成回收。另外如果 Region 未及时合并、大小异常,即便手动执行 analyze 更新统计信息,优化器仍可能选错执行计划,这种情况可以使用索引提示 (Index Hint) 来强制指定索引,规避问题。
DELETE 仅做逻辑删除标记,不会立刻物理清理,旧版本数据大量残留;即便 TiDB 自动 GC(默认约 3 小时),海量标记数据也无法短期清理完毕,读取时需要不断跳过删除标记,拖慢查询。
原大表数据分散在海量 Region 中,批量删数后大量 Region 变为空 Region / 小 Region;TiDB 后台 Region Merge 调度缓慢,一周时间仍未完成合并。limit 1 看似只取 1 行,却需要遍历数千个 Region,产生海量 RPC 请求,这是查询超时的最主要原因。
手动做一下分析看计划
等待 1-2 个 GC 周期(默认每 10 分钟一轮,缩短后更快),让底层清理掉绝大多数删除的 MVCC 旧版本数据。
健康度100但仍全表扫且慢,重点在删除后的空间和 MVCC 版本堆积。清理一半数据后,这些行变成了大量 MVCC 旧版本和标记删除的 key,GC 若没及时回收,扫描时仍要跳过海量已删版本,select * limit 1 的全表扫会被这些垃圾版本拖慢。排查方向:确认 GC safepoint 是否正常推进(SELECT * FROM mysql.tidb WHERE variable_name LIKE ‘%gc%’),检查是否有长事务或未关闭的 CDC/备份任务阻塞 GC;确认后等 GC 回收,或对相关表做 compact(tikv-ctl compact 或等待自动 compaction)回收物理空间,扫描性能即可恢复。
合并很慢,继续等等
执行计划搜下skip,如果扫的key 出现skip多可能就是mvcc,再查gc。除了这个sql,别的没问题?
大批量 DELETE 只会生成 MVCC 旧版本,不会直接释放空间,需要 GC 清理。另外 TiDB不会自动合并 Region,大量删除后容易遗留很多空 / 稀疏小 Region。 select * from tb limit 1没有 ORDER BY,语义无序,优化器可能选择扫描多条 Region。 建议两点:
- SQL 改成
SELECT * FROM tb ORDER BY 主键 LIMIT 1; - 查看该表 Region 数量,如果 Region 数量极多,可以考虑手动合并 Region,同时观察 GC 是否正常清理旧数据版本。