mutation 是什么
ALTER TABLE 的 UPDATE 与 DELETE 不是原地修改,而是以 mutation 的形式在后台按 part 重写数据。语句提交后立即返回,实际执行进度、待处理 part 数与失败原因都记录在 system.mutations 里;失败的任务会一直卡在队列中,需要人工处理。
基本信息
| 语句 | ALTER TABLE t UPDATE col = expr WHERE cond;ALTER TABLE t DELETE WHERE cond |
|---|---|
| 状态表 | system.mutations 的 is_done、parts_to_do、latest_fail_reason |
| 运维语句 | KILL MUTATION WHERE … 终止任务;SYSTEM STOP MERGES 会影响执行进度 |
| 重写范围 | mutation 以 part 为单位重写,涉及的历史数据越多耗时越长 |
| 适用定位 | 适合修正少量脏数据,不适合高频单行更新 |
典型使用场景
- 修正少量历史脏数据,例如把异常负数纠正为 0
- 按条件删除误导入的数据
- 批量回填某个字段的历史默认值
- 查看任务队列,确认重写是否已经完成
- 终止失败或误提交的变更任务
常用语句
常用语句
-- 修正脏数据:把负值改为 0
ALTER TABLE events UPDATE level = 0 WHERE level < 0;
-- 按条件删除历史数据(整分区删除用 DROP PARTITION 更快)
ALTER TABLE events DELETE WHERE ts < '2026-01-01';
-- 查看未完成的 mutation 与失败原因
SELECT command, is_done, parts_to_do, latest_fail_reason
FROM system.mutations
WHERE table = 'events' AND NOT is_done;
-- 终止卡住或提交错误的任务(确认影响后再执行)
-- KILL MUTATION WHERE database = 'analytics' AND table = 'events';状态字段读法
| 字段 | 含义 | 异常信号 |
|---|---|---|
| is_done | 任务是否完成 | 长期为 0 说明还在重写 |
| parts_to_do | 还需处理的 part 数量 | 长时间不减说明进展停滞 |
| latest_fail_reason | 最近一次失败原因 | 非空即任务已失败并卡住 |
| create_time | 任务提交时间 | 老任务堆积说明队列被堵塞 |
mutation 是重写操作,与列式存储「一次写入多次读取」的定位相悖;频繁单行更新会让后台不断重写 part,正确做法是把变更合并成一条语句再执行。
失败的 mutation 不会自行消失,会一直占用队列并阻塞同表的后续任务;处理完失败原因后必须用 KILL MUTATION 清掉它再重新提交。
同一张表的 mutation 是串行执行的:前一个任务没结束时,新提交的任务只能排队等待。批量修正前先看队列长度,避免把多个重写任务叠在一起。