月度归档: 2019 年 9 月

  • 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 ] {}  db_name.tbl_name: DB::StorageReplicatedMergeTree::queueTask()::: 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 
      [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}/${tblname}/ 目录中,删除 mutation${mutation_id}.txt 文件。

    重新装载表:

    ATTACH TABLE `${tbl_name}`;