ClickHouse 的运维思路与传统 OLTP 数据库差异很大。很多问题并不是行锁或事务阻塞,而是分区设计不合理、数据分片不均、后台合并堆积、Mutation 长时间未完成、复制队列阻塞、查询内存超限或者磁盘上的数据 Part 数量过多。
下面整理了 ClickHouse DBA 日常使用频率较高的 100 条命令,覆盖连接、数据库对象、MergeTree 表、分区、查询诊断、系统指标、数据 Part、Mutation、分布式集群、复制、用户权限、备份恢复和服务日志等场景。
本文主要面向当前主流 ClickHouse 版本。不同版本、开源自建环境和 ClickHouse Cloud 之间可能存在差异,执行前应先确认版本、部署架构和账号权限。文中的集群名、数据库名、表名、路径、IP 和用户均为示例。
DROP、TRUNCATE、KILL、ALTER DELETE、OPTIMIZE FINAL、停止后台合并、恢复副本和恢复备份等操作具有风险,生产环境执行前必须确认影响范围。
一、连接与基础信息
1. 使用 clickhouse-client 连接数据库
clickhouse-client \--host 192.168.1.10 \--port 9000 \--user dba \--password
指定数据库:
clickhouse-client --host 192.168.1.10 --database appdb --user dba --password
2. 通过 HTTPS 接口执行查询
curl -sS 'https://clickhouse.example.com:8443/?query=SELECT%201'
生产环境应使用认证和 TLS,避免将密码直接写入命令历史。
3. 查看 ClickHouse 版本
SELECT version();
4. 查看当前节点名称
SELECT hostName();
5. 查看当前数据库和用户
SELECTcurrentDatabase(),currentUser();
6. 查看服务器时区
SELECTtimezone(),now(),now('UTC');
7. 查看服务器运行时间
SELECTuptime() AS uptime_seconds,formatReadableTimeDelta(uptime()) AS uptime;
8. 查看服务器端口
SELECTname,value
FROM system.server_settings
WHERE name IN ('tcp_port', 'http_port', 'https_port', 'tcp_port_secure');
9. 查看构建选项
SELECT *
FROM system.build_options
ORDER BY name;
10. 查看当前节点告警
SELECT *
FROM system.warnings;
二、数据库、表与元数据
11. 查看所有数据库
SHOW DATABASES;
详细查看:
SELECT name, engine, data_path, metadata_path
FROM system.databases
ORDER BY name;
12. 创建数据库
CREATE DATABASE appdb;
集群范围创建:
CREATE DATABASE appdb ON CLUSTER production_cluster;
13. 查看当前数据库中的表
SHOW TABLES FROM appdb;
14. 查看表结构
DESCRIBE TABLE appdb.events;
15. 查看建表语句
SHOW CREATE TABLE appdb.events;
16. 查看所有表引擎
SELECT *
FROM system.table_engines
ORDER BY name;
17. 查看表引擎和排序键
SELECTdatabase,name,engine,partition_key,sorting_key,primary_key,total_rows,total_bytes
FROM system.tables
WHERE database = 'appdb'
ORDER BY total_bytes DESC;
18. 修改表名
RENAME TABLE appdb.events TO appdb.events_old;
19. 清空表
TRUNCATE TABLE appdb.stage_events;
集群范围执行:
TRUNCATE TABLE appdb.stage_events ON CLUSTER production_cluster;
20. 删除表
DROP TABLE appdb.events_old;
删除不可回退,必须先确认备份和依赖关系。
三、MergeTree 与表结构管理
21. 创建 MergeTree 表
CREATE TABLE appdb.events
(event_date Date,event_time DateTime,user_id UInt64,event_type LowCardinality(String),payload String
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id, event_time);
ORDER BY 决定数据物理排序和稀疏索引结构,是 ClickHouse 表设计中最重要的部分之一。
22. 创建 ReplicatedMergeTree 表
CREATE TABLE appdb.events_local ON CLUSTER production_cluster
(event_date Date,event_time DateTime,user_id UInt64,event_type LowCardinality(String)
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/appdb/events_local','{replica}'
)
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id, event_time);
23. 创建 Distributed 表
CREATE TABLE appdb.events_all ON CLUSTER production_cluster
AS appdb.events_local
ENGINE = Distributed(production_cluster,appdb,events_local,cityHash64(user_id)
);
24. 增加字段
ALTER TABLE appdb.events
ADD COLUMN source LowCardinality(String) DEFAULT 'unknown';
25. 修改字段类型
ALTER TABLE appdb.events
MODIFY COLUMN payload String;
修改类型可能触发数据重写,应评估表规模和兼容性。
26. 删除字段
ALTER TABLE appdb.events
DROP COLUMN payload;
27. 增加跳数索引
ALTER TABLE appdb.events
ADD INDEX idx_event_type event_type TYPE set(100) GRANULARITY 4;
对已有数据物化索引:
ALTER TABLE appdb.events
MATERIALIZE INDEX idx_event_type;
28. 查看表索引
SELECTdatabase,table,name,type,expression,granularity
FROM system.data_skipping_indices
WHERE database = 'appdb'AND table = 'events';
29. 增加 TTL
ALTER TABLE appdb.events
MODIFY TTL event_date + INTERVAL 180 DAY DELETE;
30. 物化 TTL
ALTER TABLE appdb.events
MATERIALIZE TTL;
该操作可能触发大量后台合并和数据删除,应在低峰期评估执行。
四、数据查询与导入导出
31. 插入数据
INSERT INTO appdb.events
VALUES
('2026-07-27','2026-07-27 10:00:00',1001,'login','{}'
);
32. 从查询结果插入数据
INSERT INTO appdb.events
SELECT *
FROM appdb.events_stage
WHERE event_date = '2026-07-27';
33. 查询表行数
SELECT count()
FROM appdb.events;
34. 查看近一天数据量
SELECTevent_type,count() AS rows
FROM appdb.events
WHERE event_time >= now() - INTERVAL 1 DAY
GROUP BY event_type
ORDER BY rows DESC;
35. 查看查询执行计划
EXPLAIN
SELECT count()
FROM appdb.events
WHERE user_id = 1001;
36. 查看执行管道
EXPLAIN PIPELINE
SELECT count()
FROM appdb.events
WHERE event_date >= today() - 7;
37. 查看索引裁剪信息
EXPLAIN indexes = 1
SELECT *
FROM appdb.events
WHERE event_date = today()AND user_id = 1001;
38. 导出 CSV
clickhouse-client \--query="SELECT * FROM appdb.events FORMAT CSVWithNames" \> events.csv
39. 导入 CSV
clickhouse-client \--query="INSERT INTO appdb.events FORMAT CSV" \< events.csv
如果文件包含表头,应使用与文件匹配的格式。
40. 使用 clickhouse-local 查询文件
clickhouse-local \--file events.csv \--input-format CSVWithNames \--query "SELECT event_type, count() FROM table GROUP BY event_type"
五、会话、查询与性能诊断
41. 查看正在执行的查询
SELECTquery_id,user,address,elapsed,read_rows,read_bytes,memory_usage,query
FROM system.processes
ORDER BY elapsed DESC;
42. 查看集群全部节点上的查询
SELECThostName() AS host,query_id,user,elapsed,memory_usage,query
FROM clusterAllReplicas('production_cluster', system.processes)
ORDER BY elapsed DESC;
43. 终止指定查询
KILL QUERY
WHERE query_id = 'query-id'
SYNC;
44. 查看近期执行失败的 SQL
SELECTevent_time,query_id,user,exception_code,exception,query
FROM system.query_log
WHERE type IN ('ExceptionBeforeStart', 'ExceptionWhileProcessing')AND event_time >= now() - INTERVAL 1 HOUR
ORDER BY event_time DESC;
45. 查看耗时最高的 SQL
SELECTquery_id,user,query_duration_ms,read_rows,formatReadableSize(read_bytes) AS read_size,formatReadableSize(memory_usage) AS memory,query
FROM system.query_log
WHERE type = 'QueryFinish'AND event_time >= now() - INTERVAL 1 HOUR
ORDER BY query_duration_ms DESC
LIMIT 20;
46. 查看内存消耗最高的 SQL
SELECTquery_id,user,formatReadableSize(memory_usage) AS memory,query_duration_ms,query
FROM system.query_log
WHERE type = 'QueryFinish'AND event_time >= now() - INTERVAL 1 HOUR
ORDER BY memory_usage DESC
LIMIT 20;
47. 查看当前指标
SELECTmetric,value,description
FROM system.metrics
ORDER BY metric;
48. 查看累计事件
SELECTevent,value,description
FROM system.events
ORDER BY value DESC;
49. 查看异步指标
SELECTmetric,value
FROM system.asynchronous_metrics
ORDER BY metric;
50. 刷新系统日志表
SYSTEM FLUSH LOGS;
执行后再查询 system.query_log,可以减少日志尚未落表造成的遗漏。
六、磁盘、数据 Part 与 Mutation
51. 查看磁盘空间
SELECTname,path,formatReadableSize(free_space) AS free,formatReadableSize(total_space) AS total,round(free_space * 100 / total_space, 2) AS free_pct
FROM system.disks;
52. 查看存储策略
SELECT *
FROM system.storage_policies
ORDER BY policy_name, volume_name, volume_priority;
53. 查看大表排行
SELECTdatabase,table,sum(rows) AS rows,formatReadableSize(sum(bytes_on_disk)) AS disk_size
FROM system.parts
WHERE active
GROUP BY database, table
ORDER BY sum(bytes_on_disk) DESC
LIMIT 20;
54. 查看分区大小
SELECTdatabase,table,partition,sum(rows) AS rows,count() AS parts,formatReadableSize(sum(bytes_on_disk)) AS disk_size
FROM system.parts
WHERE activeAND database = 'appdb'AND table = 'events'
GROUP BY database, table, partition
ORDER BY partition;
55. 查看 Part 数量
SELECTdatabase,table,count() AS active_parts
FROM system.parts
WHERE active
GROUP BY database, table
ORDER BY active_parts DESC;
Part 数量过多通常与写入批次过小或后台合并跟不上有关。
56. 查看正在进行的合并
SELECTdatabase,table,elapsed,progress,num_parts,result_part_name,formatReadableSize(total_size_bytes_compressed) AS size
FROM system.merges
ORDER BY elapsed DESC;
57. 强制合并数据
OPTIMIZE TABLE appdb.events FINAL;
FINAL 可能产生大量 CPU、磁盘 I/O 和临时空间消耗,不应作为日常定时维护命令。
58. 查看 Mutation
SELECTdatabase,table,mutation_id,command,create_time,parts_to_do,is_done,latest_fail_reason
FROM system.mutations
ORDER BY create_time DESC;
59. 异步删除数据
ALTER TABLE appdb.events
DELETE WHERE event_date < today() - 180;
该操作会创建 Mutation。大范围删除优先考虑按分区删除。
60. 删除整个分区
ALTER TABLE appdb.events
DROP PARTITION '202601';
按分区删除通常比行级 Mutation 更高效,但必须确认分区表达式和目标分区值。
七、分布式集群与复制
61. 查看集群拓扑
SELECTcluster,shard_num,replica_num,host_name,host_address,port,is_local
FROM system.clusters
ORDER BY cluster, shard_num, replica_num;
62. 在集群所有节点执行查询
SELECThostName() AS host,version()
FROM clusterAllReplicas('production_cluster', system.one);
63. 查看副本状态
SELECTdatabase,table,is_leader,is_readonly,is_session_expired,queue_size,inserts_in_queue,merges_in_queue,absolute_delay,zookeeper_exception
FROM system.replicas
ORDER BY absolute_delay DESC;
64. 查看复制队列
SELECTdatabase,table,replica_name,position,node_name,type,create_time,num_tries,last_exception
FROM system.replication_queue
ORDER BY create_time;
65. 等待副本同步
SYSTEM SYNC REPLICA appdb.events_local;
66. 重启单表副本状态
SYSTEM RESTART REPLICA appdb.events_local;
执行期间表会短暂不可用,只应在确认副本状态异常后使用。
67. 查看分布式发送队列
SELECTdatabase,table,data_path,is_blocked,error_count,last_exception
FROM system.distribution_queue
ORDER BY error_count DESC;
68. 刷新 Distributed 表发送队列
SYSTEM FLUSH DISTRIBUTED appdb.events_all;
69. 查看 Keeper/ZooKeeper 连接状态
SELECT *
FROM system.zookeeper_connection;
70. 查看 ON CLUSTER DDL 队列
SELECTentry,host,port,status,exception_code,exception_text,query
FROM system.distributed_ddl_queue
ORDER BY entry DESC;
八、用户、权限与参数
71. 查看用户
SHOW USERS;
详细查看:
SELECT *
FROM system.users;
72. 创建用户
CREATE USER appuser
IDENTIFIED WITH sha256_password BY 'Replace_With_Strong_Password';
73. 修改用户密码
ALTER USER appuser
IDENTIFIED WITH sha256_password BY 'Replace_With_New_Strong_Password';
74. 创建角色
CREATE ROLE readonly_role;
75. 授予只读权限
GRANT SELECT ON appdb.* TO readonly_role;
GRANT readonly_role TO appuser;
76. 回收权限
REVOKE SELECT ON appdb.* FROM readonly_role;
77. 查看授权
SHOW GRANTS FOR appuser;
78. 查看当前会话参数
SELECTname,value,changed,description
FROM system.settings
ORDER BY name;
79. 修改当前会话内存限制
SET max_memory_usage = 10000000000;
该设置只影响当前会话,具体值应结合节点内存和并发量确定。
80. 设置查询最大执行时间
SET max_execution_time = 300;
九、备份、恢复与数据维护
81. 备份单表到本地备份磁盘
BACKUP TABLE appdb.events
TO Disk('backups', 'appdb_events_20260727.zip');
需要先在服务器配置中定义 backups 磁盘。
82. 备份整个数据库
BACKUP DATABASE appdb
TO Disk('backups', 'appdb_20260727.zip');
83. 异步执行备份
BACKUP DATABASE appdb
TO Disk('backups', 'appdb_async_20260727.zip')
ASYNC;
84. 查看备份任务
SELECT *
FROM system.backups
ORDER BY start_time DESC;
85. 恢复单表
RESTORE TABLE appdb.events
FROM Disk('backups', 'appdb_events_20260727.zip');
86. 恢复为新表
RESTORE TABLE appdb.events AS appdb.events_restore
FROM Disk('backups', 'appdb_events_20260727.zip');
恢复到新表更适合先做数据校验。
87. 冻结表分区
ALTER TABLE appdb.events
FREEZE PARTITION '202607'
WITH NAME 'events_202607';
FREEZE 生成硬链接快照,但不等同于完整的异地备份。
88. 解除冻结备份
SYSTEM UNFREEZE WITH NAME 'events_202607';
89. 停止指定表后台合并
SYSTEM STOP MERGES appdb.events;
90. 恢复指定表后台合并
SYSTEM START MERGES appdb.events;
长期停止合并会造成 Part 堆积,只能作为短期故障处理手段。
十、服务、日志与巡检
91. 查看 ClickHouse 服务状态
systemctl status clickhouse-server
92. 启动 ClickHouse
systemctl start clickhouse-server
93. 停止 ClickHouse
systemctl stop clickhouse-server
停库前应确认业务、复制和后台任务状态。
94. 重启 ClickHouse
systemctl restart clickhouse-server
95. 查看服务日志
journalctl -u clickhouse-server --since "1 hour ago"
96. 查看默认日志文件
tail -200 /var/log/clickhouse-server/clickhouse-server.log
tail -200 /var/log/clickhouse-server/clickhouse-server.err.log
实际路径以配置文件为准。
97. 查看 ClickHouse 进程
ps -ef | grep '[c]lickhouse-server'
98. 查看监听端口
ss -lntp | grep -E ':(8123|9000|9009|8443|9440)\b'
不同协议和安全配置使用的端口可能不同。
99. 查看磁盘和 I/O
df -h
df -i
iostat -x 1 5
ClickHouse 对磁盘吞吐和延迟较敏感,空间告警还要结合 Part、Merge、Mutation 和复制队列一起分析。
100. 执行快速巡检摘要
SELECT 'running_queries' AS item, toString(count()) AS value
FROM system.processes
UNION ALL
SELECT 'active_merges', toString(count())
FROM system.merges
UNION ALL
SELECT 'unfinished_mutations', toString(count())
FROM system.mutations
WHERE NOT is_done
UNION ALL
SELECT 'replica_queue', toString(sum(queue_size))
FROM system.replicas
UNION ALL
SELECT 'disk_free',arrayStringConcat(groupArray(concat(name, ':', formatReadableSize(free_space))),', ')
FROM system.disks;
结语
ClickHouse DBA 排查问题时,不能只盯着 CPU 和一条慢 SQL。更有效的顺序通常是先确认磁盘空间和节点状态,再看 system.processes、system.query_log、system.parts、system.merges、system.mutations、system.replicas 和 system.replication_queue。
如果 Part 数量持续增长,通常要检查写入批次和合并能力;如果 Mutation 长时间不结束,要判断是否扫描和重写了过多数据;如果副本延迟,则要进一步区分网络、Keeper、复制队列和磁盘 I/O 问题。
真正适合生产环境的 ClickHouse 运维,不是频繁执行 OPTIMIZE FINAL,而是通过合理的分区、排序键、批量写入、存储策略和复制设计,让后台任务能够长期稳定运行。
官方资料
- ClickHouse 官方文档:https://clickhouse.com/docs/
- 系统表:https://clickhouse.com/docs/reference/system-tables/overview
- SYSTEM 命令:https://clickhouse.com/docs/reference/statements/system
- 备份与恢复:https://clickhouse.com/docs/operations/backup/overview