ClickHouse ON CLUSTER分布式DDL执行失败的排查与处理
ClickHouse中ON CLUSTER分布式DDL执行失败时,如何排查和处理?请解释system.ddl_queue和system.ddl_log的定位方法、分布式DDL任务的ZooKeeper路径查看、以及如何清理卡住的DDL任务(如某节点宕机导致的无限等待)。给出一个手动清理ZK中阻塞DDL任务的操作步骤。
回答
编译有声
ClickHouse分布式DDL故障排查:
1. 查看DDL执行状态:
-- 当前DDL队列(未完成的任务)
SELECT * FROM system.ddl_queue;
-- DDL执行历史
SELECT * FROM system.ddl_log ORDER BY event_time DESC;
-- 关键字段:
-- query: 执行的DDL语句
-- host: 执行节点
-- status: COMPLETED/FAILED/UNKNOWN
-- exception: 错误信息
2. ZooKeeper路径查看:
# 查看DDL任务队列
clickhouse-keeper-client get /clickhouse/task_queue/ddl/
# 或
echo 'get /clickhouse/task_queue/ddl/' | clickhouse-zookeeper-cli
# 查看具体DDL任务内容
clickhouse-zookeeper-cli get /clickhouse/task_queue/ddl/query-0000000001
# 返回:DDL语句、目标host列表、创建时间
3. 常见失败原因:
| 错误 | 原因 | 解决 |
|---|---|---|
Connection refused | 某节点宕机 | 恢复节点或手动清理 |
Timeout exceeded | DDL超时(默认180s) | distributed_ddl_task_timeout加大 |
Table already exists | 部分节点已执行 | 检查一致性 |
Code: 60 | 表不存在或其他节点不一致 | 逐个节点检查 |
4. 清理阻塞的DDL任务:
# 1. 找到卡住的DDL任务ID
clickhouse-client -q "SELECT * FROM system.ddl_queue"
# 2. 用ZooKeeper客户端删除
clickhouse-keeper-client rmr /clickhouse/task_queue/ddl/query-0000000001
# 3. 或在DDL查询中设置超时
clickhouse-client --distributed_ddl_task_timeout=0 \
-q "SYSTEM DROP DNS CACHE" # 先执行一个简单分布式DDL测试
# 4. 重启节点清理所有DDL队列(应急)
# systemctl restart clickhouse-server
5. 预防措施:
# config.xml 配置
distributed_ddl_task_timeout: 300 # 增大超时
distributed_ddl_output_mode: distributed # 返回所有节点的执行结果
# 生产建议:
# 1. DDL操作在低峰期执行
# 2. 先在单节点测试再ON CLUSTER
# 3. 使用`SYSTEM SYNC REPLICA`确保所有节点同步
6. 强制跳过失败节点:
# 如果某个节点永久损坏,在DDL中排除它
# 方法:修改ZK DDL任务,从host_list中移除该节点
# 或直接删除该节点在ZK中的条目
clickhouse-keeper-cli delete /clickhouse/replicas/{node_name}