ClickHouse 复制队列:属于副本,不属于表
在 CH-Ops(自托管 ClickHouse 管理 GUI)上测试 1 shard 2 replicas 时,作者停了 Node B,从 Node A 插入数据,然后看 Node B 的队列有积压、Node A 队列却空。第一直觉是"集群级待复制总量"——但 A 刚收到新数据应该也有待同步项才对。这个不匹配引出了核心心智模型。
队列属于副本,不属于表
ReplicatedMergeTree 表有多个副本持有相同数据,容易想象成副本间一根共享管道。不是。每个副本维护自己的本地复制队列。
Replica 1 → queue_size = 0
Replica 2 → queue_size = 25
这不是"25 个操作在中间等两个副本取",而是Replica 2 自己有 25 个未完成任务。Node B 恢复后队列几秒排空、数据出现。
任务从哪来
ClickHouse 复制不是副本间直接拷贝,中间有协调层:ClickHouse Keeper 持有复制日志——表上发生过的操作记录。发生复制事件(part 插入、merge、mutation)时,操作记入 Keeper;每个副本 watch 日志,算出"我要做什么才能追上",变成任务落进该副本自己的队列。任务可能是:fetch part、merge parts、apply mutation、drop range。
队列本质是从共享日志生成、但本地执行的待办清单。
在哪看:system.replicas
SELECT database, table, replica_name, is_leader, is_readonly,
queue_size, inserts_in_queue, merges_in_queue,
part_mutations_in_queue, absolute_delay
FROM system.replicas;
示例输出:
┌─replica_name─┬─queue_size─┬─inserts_in_queue─┬─merges_in_queue─┬─absolute_delay─┐
│ replica_1 │ 0 │ 0 │ 0 │ 0 │
│ replica_2 │ 12 │ 3 │ 9 │ 4 │
└──────────────┴────────────┴──────────────────┴─────────────────┴────────────────┘
queue_size 是总量,inserts_in_queue/merges_in_queue 分开看积压来源,absolute_delay 反映滞后秒数。
实践建议
- 排查复制积压先定位是哪个副本:队列是每副本视角,别当集群级读数;
- 看 system.replicas 分维度判断积压类型(insert vs merge vs mutation);
- 副本长期 down 后恢复,队列排空快不代表数据已全部落盘——结合 absolute_delay 与数据校验确认。
来源:Understanding the Replication Queue in ClickHouse - DEV Community