ClickHouse Mutation
在 ClickHouse 中,ALTER UPDATE/DELETE
等,被称为 Mutation。
一、Mutation 异步执行注意事项
Mutation 是异步执行的,所以如果有后续任何类型的 Query,无论是INSERT
、SELECT
、ALTER
等,如果这些 Query 的条件对 Mutation 的结果有依赖,那么都应该等待 Mutation 完全结束之后再操作。
确认 Mutation 是否完成,可以通过查询system
.mutations
表中是否有相关的”is_done
=0″记录来完成。
检测是否有未完成的 Mutations:
SELECT COUNT() FROM `system`.mutations
WHERE `database`='${db_name}' AND `table`='${tbl_name}' AND is_done=0;
二、删除挂起的 Mutation
某同学曾经在ALTER UPDATE
中错误地赋值,将NULL
赋给不可为NULL
的字段,从而使 Mutation 无法正确执行,然后就一直挂在系统里,而且不断报错。
2019.09.05 10:46:11.450867 [ 9 ] {} <Error> db_name.tbl_name: DB::StorageReplicatedMergeTree::queueTask()::<lambda(DB::StorageReplicatedMergeTree::LogEntryPtr&)>: Code: 349, e.displayText() = DB::Exception: Cannot convert NULL value to non-Nullable type, Stack trace:
此时便需要将挂起的 Mutation 清理掉。
首先,通过
SELECT * FROM `system`.mutations
WHERE `database`='${db_name}' AND `table`='${tbl_name}' AND is_done=0;
查得与挂起 Mutation 相关记录的mutation_id
字段值等相关信息。然后进行清理。
清理有两种手法:
1. 系统自带清理
语法:
KILL MUTATION [ON CLUSTER cluster]
WHERE <where expression to SELECT FROM system.mutations query>
[TEST]
[FORMAT format]
例子:
-- 取消并移除某单表的所有 Mutations:
KILL MUTATION WHERE database = '${db_name}' AND table = '${tbl_name}'
-- 取消某特定的 Mutation:
KILL MUTATION WHERE database = '${db_name}' AND table = '${tbl_name}' AND mutation_id = '${mutation_id}'
官方文档参考:KILL MUTATION
2. 手工清理
有两种 Case,一种是复制表,一种是非复制表。
2.1 对于复制表,处理 ZooKeeper 中相应的 ZNode 即可。
在 ZooKeeper 中找到znode /${path_to_table}/mutations/${mutation_id}
,将其删除。
2.2 对于非复制表
先将表卸载:
DETACH TABLE `${tbl_name}`;
从 ${clickhouse_data_dir}/${db_name}/${tbl_name}/
目录中,删除 mutation_${mutation_id}.txt 文件。
重新装载表:
ATTACH TABLE `${tbl_name}`;