ClickHouse(CK)里的 DELETE,为什么在生产环境中被称作“难用”,甚至可能成为“灾难”?


一、ClickHouse DELETE 的本质

  1. ClickHouse 是列式存储 + MergeTree 系列表引擎

    • 数据按 part(数据块) 存储
    • 写入是 append-only
    • 查询通过合并多个 part 实现
  2. DELETE 不是真正逐行删除

    • DELETE 语句会生成 标记(mutation)
    • 标记要删除的行,但物理删除发生在 后台 merge 过程中
  3. DELETE 的执行流程

用户执行 DELETE -> CK 生成 mutation -> mutation 标记数据块中对应行 -> merge 背景任务执行,物理删除行

注意:这不是即时删除,删除完成可能要几分钟甚至几小时,取决于数据量和后台 merge 任务。


二、为什么 DELETE 很难用

1️⃣ 延迟高(不是实时生效)

  • 大量数据 DELETE 可能几分钟甚至几个小时才生效
  • 查询仍然可能返回被删除的数据(直到 mutation 完成)

2️⃣ 资源消耗巨大

  • DELETE 触发 merge
  • 大量行被标记后,后台 merge 会 扫描、重写整个数据块
  • 数据量大时,CPU、IO、磁盘压力非常大
  • 对生产表尤其是大表,可能导致查询延迟飙升

3️⃣ 并发冲突

  • DELETE mutation 与 INSERT、OPTIMIZE、TTL 等操作竞争资源
  • 可能导致 merge 堵塞、查询变慢、甚至部分 mutation 失败

4️⃣ 无法精准控制

  • DELETE 只能按 条件匹配行
  • 对大表删除全表或大范围行几乎是灾难
  • 小心误删:一旦 DELETE 执行,虽然不是立即物理删除,但 mutation 会生成,回滚困难

三、生产环境中的灾难案例

  1. 大表误删

    • DELETE 条件写错,覆盖几十亿行
    • mutation 触发背景 merge
    • CPU/IO 飙升,查询变慢,业务系统卡顿
  2. 高并发 DELETE

    • 与 INSERT / SELECT 并行执行
    • merge 队列堆积
    • 影响整个数据库实例性能
  3. TTL + DELETE 混用

    • TTL 触发 merge + DELETE mutation
    • 数据块被频繁重写,导致磁盘 I/O 高峰
    • 查询响应时间延长
  4. 删除大范围行

    • CK 不是行存储,删除大量行等于 全表重写
    • 对数十亿行大表,几小时甚至几十小时才能完成

所以 CK DELETE 只能算 “轻量标记删除 + 小范围行删除”,不适合频繁大规模删除


四、生产中可替代方案

  1. 分区管理

    • DROP PARTITION 替代 DELETE 大范围删除
    • 删除粒度:分区而不是行
    • 性能最好,立即生效
  2. TTL + 覆盖写

    • 对旧数据用 TTL 自动过期
    • 新版本覆盖写,而不是直接 DELETE
  3. ReplacingMergeTree / CollapsingMergeTree

    • 用版本列或 sign 列实现“逻辑删除”
    • 不直接物理删除行
  4. 副本表 / 历史表

    • 如果数据量大,不删除原表,写入新的快照表
    • 查询时只查询快照表

五、总结

特性 / 风险描述
DELETE 本质append-only + mutation 标记,不是即时物理删除
延迟大表删除可能几小时后才生效
资源消耗背景 merge 会重写数据块,CPU/IO 占用高
并发问题DELETE 与 INSERT/SELECT 冲突,可能堵塞 merge
风险场景大表误删、高并发删除、TTL + DELETE 混用

💡 结论

ClickHouse 的 DELETE 不是行级即时删除,生产环境大表频繁 DELETE 会导致性能灾难。
推荐策略:用分区 DROP、TTL 或逻辑删除替代 DELETE。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐