TiDB删除大量数据需要注意什么

发布于:2025-03-17 ⋅ 阅读:(14) ⋅ 点赞:(0)


在 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 中的海量数据。