ClickHouse Mutation

ClickHouse Mutation

在 ClickHouse 中,ALTER UPDATE/DELETE 等,被称为 Mutation。

一、Mutation 异步执行注意事项

Mutation 是异步执行的,所以如果有后续任何类型的 Query,无论是INSERTSELECTALTER等,如果这些 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}`;

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.