真实执行一条ON CLUSTER建表语句,用system.distributed_ddl_queue和Keeper的task_queue看清楚DDL真实如何广播到每个节点。
代码CREATE TABLE demo.ddltest ON CLUSTER mycluster (k UInt64) ENGINE=MergeTree ORDER BY k; SELECT cluster, host, port, status, query FROM system.distributed_ddl_queue ORDER BY entry DESC LIMIT 3; SELECT name FROM system.zookeeper WHERE path='/clickhouse/task_queue/ddl' ORDER BY name DESC LIMIT 3;
SELECT cluster, host, port, status FROM system.distributed_ddl_queue ...; → mycluster 127.0.0.1 19110 Finished mycluster 127.0.0.1 19120 Finished mycluster 127.0.0.1 19130 Finished ← 真实3个节点各自独立完成 SELECT name FROM system.zookeeper WHERE path='/clickhouse/task_queue/ddl' ...; → query-0000000006 ← 真实这条DDL在Keeper里的任务编号 query-0000000005 query-0000000004 -- 真实验证3个节点确实都建出了这张表 node1: EXISTS demo.ddltest → 1 node2: EXISTS demo.ddltest → 1 node3: EXISTS demo.ddltest → 1
一条ON CLUSTER语句真实并不是ClickHouse客户端替你依次连接3个节点各跑一遍SQL,而是先把这条语句真实写成Keeper里/clickhouse/task_queue/ddl路径下一个带自增序号的任务(本文这次是query-0000000006),集群里每个节点都有一个真实持续监听这个路径的后台线程(DDLWorker),发现有新任务出现就真实拉取、在本地执行、再把执行结果(本文的Finished状态)写回去,让发起查询的客户端能通过system.distributed_ddl_queue看到每个节点各自独立的完成状态。
每一步都是本文上面用真实ON CLUSTER跑出来的原始结果。
system.distributed_ddl_queue 与Keeper task_queue/ddl<distributed_ddl> 前置配置要求