https://inasa.dev/blog/rss.xml

ClickHouse | ReplacingMergeTree使用记录

2023-08-13

删除具有相同排序键值(ORDER BY 表部分,而不是 PRIMARY KEY)的重复条目

ENGINE = ReplacingMergeTree([ver [, is_deleted]])

ReplacingMergeTree后面会跟一个或两个列

  • ver表示版本号的列

    • 类型 UInt*DateDateTimeDateTime64
    • 如果ver未指定,则使用选择中的最后一个
    • 如果ver已指定,则使用最大版本
    • 这里可以参考官网的示例
  • is_deleted表示删除的状态

    • 类型必须是 UInt8

    • 只有设置了ver才可以设置is_deleted

    • 合并期间使用的列名称,用于确定该行中的数据是否代表状态或要删除

      • 1 是“已删除”行
      • 0 是“状态”行
    • 当使用 OPTIMIZE table {table_name} FINAL CLEANUPOPTIMIZE table {table_name} FINAL 时,或者引擎设置 clean_deleted_rows 设置为 Always 时,将删除该行

      • 删除是异步的

      • 默认一条insert插入的数据为同一个数据分区,不同insert插入的数据为不同的分区,所以ReplacingMergeTree是以分区为单位进行去重的,也就是说只有在相同的数据分区内,重复数据才可以被删除掉。只有数据合并完成后,才可以使用引擎特性进行去重。

      • 修改config.xml

        •     <merge_tree>
                      <max_suspicious_broken_parts>5</max_suspicious_broken_parts>
                      <clean_deleted_rows>Always</clean_deleted_rows>
              </merge_tree>
          
    • 无论对数据进行什么操作,都必须增加版本。如果两个插入的行具有相同的版本号,则保留最后插入的行

如果指定了ver,但是没有指定is_deleted,旧的数据会依然保存在表里。

select * from {table_name}//查出所有数据,包括新旧
select * from {table_name} final //只查询新数据,感觉很慢,需要个好几秒

  • https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/replacingmergetree
  • https://github.com/ClickHouse/ClickHouse/issues/8322
  • https://clickhouse.com/docs/en/operations/settings/merge-tree-settings#clean_deleted_rows