在 TiDB 中删除大量数据时,需谨慎处理以避免性能下降、事务冲突或存储空间未及时释放等问题。以下是关键注意事项和优化建议:
---
1. 避免大事务
- 问题:直接执行 `DELETE FROM table` 会导致超大事务,可能触发 TiDB 事务限制(默认单事务限制为 `txn-total-size-limit=100MB`),导致失败或性能问题。
- 解决方案:
- 分批次删除:使用 `LIMIT` 和循环分批删除,控制每批数据量(例如每次删除 1 万条):
``` sql
DELETE FROM table WHERE 条件 LIMIT 10000;
```
- 脚本化处理:通过脚本(如 Python、Shell)或存储过程自动执行分批删除,直至无数据可删。
---
2. 合理处理 GC(Garbage Collection)
- 问题:TiDB 使用 MVCC 机制,删除数据后旧版本不会立即清理,需等待 GC 回收(默认 10 分钟)。
- 优化建议:
- 缩短 GC 周期(谨慎操作):
```sql
-- 调整 GC 生命周期为 5 分钟(默认 10m)
SET GLOBAL tidb_gc_life_time = '5m';
```
- 手动触发 GC(必要时):
sql
-- 触发当前 GC(默认自动运行,无需手动触发)
- 操作后恢复 GC 设置:避免影响长事务运行。
---
3. 减少对在线业务的影响
- 选择低峰期操作:避免在业务高峰期执行删除,减少锁冲突和延迟。
- 调整 TiDB 参数:
- 增大 `tidb_txn_commit_batch_size`(默认 1MB)以提升批量提交效率。
- 监控 TiKV 的磁盘 I/O、CPU 压力,必要时横向扩展节点。
---
4. 使用分区表优化删除效率
- 场景:按时间或范围删除数据(如清理历史日志)。
- 优化方法:
- 预先设计分区表:按时间范围分区。
- 直接 `TRUNCATE` 分区:替代 `DELETE`,秒级完成。
``` sql
ALTER TABLE table TRUNCATE PARTITION p202301;
```
---
5. 更新统计信息
- 问题:删除大量数据后,统计信息可能不准确,导致执行计划劣化。
- 解决方案:
``` sql
ANALYZE TABLE table;
```
---
6. 考虑物理删除 VS 逻辑删除
- 逻辑删除:通过 `is_deleted` 标记数据,避免物理删除的 I/O 开销,但需业务层适配。
- 物理删除:必须清理数据时,优先使用分批次或分区删除。
---
7. 备份与恢复(兜底方案)
- 备份数据:删除前确认是否需要备份(如使用 Dumpling 或 BR)。
- 开启 TiDB 异步提交(`tidb_enable_async_commit`)或 1PC(`tidb_enable_1pc`)提升事务提交效率。
---
8. 监控与日志
- 监控指标:
- `TiKV_GC_worker`:GC 任务进度。
- `TiDB_txn_ops`:事务提交速率。
- 慢查询日志:定位删除导致的性能瓶颈。
- 日志分析:关注 `tidb.log` 中的 GC 警告或事务冲突信息。
---
总结操作流程
1. 评估数据量:确认待删除数据范围(如 `WHERE create_time < '2023-01-01'`)。
2. 选择策略:优先分区表 > 分批次删除 > 逻辑删除。
3. 调整 GC 参数:缩短 `tidb_gc_life_time`(操作后还原)。
4. 分批删除:通过脚本控制批次大小和间隔。
5. 触发统计信息更新:执行 `ANALYZE`。
6. 监控资源:确保 TiKV 磁盘和 CPU 正常。
通过合理设计,可以高效安全地删除 TiDB 中的海量数据。