严格监控长事务,防止其阻塞全局 safe point 的推进。
是的,长事务还是要监控一下的
垃圾回收(GC)是基于整个集群级别的,而不是针对单张表的
IO 影响控制 有机制 。可通过 tidb_gc_delete_rate_limit 等参数进行限流。
gc推进慢的话safe point也对事务有影响
嗯,长时间运行的事务尤其显著
GC是并发的,不是串行,由 tidb_gc_concurrency参数控制
那其实这些参数设置也要综合考量呢
不是 “按表” 阻塞,而是全局阻塞 safe point。
长事务会导致积累垃圾
safe_point = 现在时刻 - gc_life_time
但 safe_point 不能超过任何正在运行事务的 start_ts。
safe point 是全局统一。长事务确实会影响其他表的gc
兜底机制:即使存在超长事务,当阻塞时间超过tidb_gc_max_wait_time(默认24小时)后,会强制推进Safe Point,牺牲该长事务的一致性来保证集群正常GC,避免历史版本无限堆积。在超时阈值内,所有表都会受影响;超过阈值后,GC强制推进,长事务可能失败。
及时执行扫描和信息统计还是有用的
还是得从业务端去尽可能控制长事务
问题 1:长事务是否会导致所有表延迟清理垃圾数据?
是的,你的理解基本正确。
根据手册第 9.2.0.10.1 节的说明:
机制原理:
- TiDB 采用 MVCC 机制,DELETE/UPDATE 操作不会立即删除旧数据,而是保留多个版本
- GC 会定期清理超过 tidb_gc_life_time(默认 10 分钟)的旧版本数据
- GC safe point 不会超过任何正在执行事务的 start_ts
影响范围:
- 是全局性的,不是按表级别的
- 一个长事务会阻塞整个集群的 GC 进度
- 所有表的旧版本数据都无法被清理,即使这些表和长事务无关
原因:
TiDB 使用 Google Percolator 分布式事务模型
- 事务有 Primary Lock 和 Secondary Lock
- GC 需要确保不会清理掉事务可能需要的数据版本
- 为了保证事务隔离性,safe point 必须保持在最老活跃事务的 start_ts 之前
问题 2:10 张表的垃圾数据清理是并行还是串行?
是并行清理的。
根据手册第 1245-1246 页的 GC 工作流程:
GC 三阶段:
- Resolve Locks - 回滚 safe point 之前未提交的事务锁
- Delete Ranges - 处理 DROP TABLE/DROP INDEX 的大范围删除
- Do GC - 实际清理 MVCC 旧版本数据
并行机制:
- TiDB 5.0+ 使用 DISTRIBUTED GC 模式
- GC 任务按 Region 级别分发到各个 TiKV 节点
- 多个 TiKV 节点可以并行处理各自负责的 Region
- 不是按表串行,而是按 Region 并行
并发控制参数:
┌────────────────────────────┬───────────────────┬──────────┐
│ 参数 │ 说明 │ 默认值 │
├────────────────────────────┼───────────────────┼──────────┤
│ tidb_gc_concurrency │ GC 并发协程数 │ 2 │
├────────────────────────────┼───────────────────┼──────────┤
│ gc.max-write-bytes-per-sec │ TiKV 端 GC 写限速 │ 0 (不限) │
└────────────────────────────┴───────────────────┴──────────┘
问题 3:有没有机制控制对 IO 的影响?
有的,TiDB 提供了多种 IO 保护机制:
- TiKV 端写限速
通过 tikv-ctl 设置 GC 写入限速
tikv-ctl --host=ip:port modify-tikv-config -n gc.max-write-bytes-per-sec -v 10MB
- GC 在 Compaction Filter 中执行 (TiDB 5.0+)
TiKV 配置
[gc]
enable-compaction-filter = true # 默认开启
- 利用 RocksDB Compaction 过程顺便清理垃圾数据
- 避免单独的 GC 写入放大
- 显著降低 IO 影响
- 调整 GC 频率和保留时间
– 调整 GC 运行间隔 (默认 10s)
SET GLOBAL tidb_gc_run_interval = ‘10m’;
– 调整 GC 数据保留时间 (默认 10m)
SET GLOBAL tidb_gc_life_time = ‘1h’;
- 监控 GC 状态
– 查看 GC safe point
SELECT * FROM mysql.tidb WHERE variable_name = ‘tikv_gc_safe_point’;
– 查看 GC 配置
SELECT * FROM mysql.tidb WHERE variable_name LIKE ‘tikv_gc%’;
生产环境建议
┌────────────────┬──────────────────────────────────────────────────────┐
│ 场景 │ 建议配置 │
├────────────────┼──────────────────────────────────────────────────────┤
│ 长事务不可避免 │ 增大 tidb_gc_life_time 到 1-2 小时,给长事务留足时间 │
├────────────────┼──────────────────────────────────────────────────────┤
│ IO 压力大 │ 设置 gc.max-write-bytes-per-sec 为 50-100MB/s │
├────────────────┼──────────────────────────────────────────────────────┤
│ 大量 DELETE 后 │ 手动执行 ALTER TABLE … COMPACT 加速清理 │
├────────────────┼──────────────────────────────────────────────────────┤
│ 避免长事务 │ 监控 TIDB_TRX 表,设置告警阈值 │
└────────────────┴──────────────────────────────────────────────────────┘
监控长事务的 SQL:
SELECT * FROM information_schema.TIDB_TRX
ORDER BY START_TIME LIMIT 10;
如果经常有长事务,建议从业务层面优化,比如:
- 分批处理大数据量操作
- 避免在事务中进行外部 API 调用
- 使用 SET tidb_batch_commit = 1 分批提交
是并行的