ClickHouse system.*_log 表几十 GB?先清后关

线上一台 ClickHouse 跑了两个月,磁盘吃掉几十 GB。查一下:

SELECT database, table,
       formatReadableSize(sum(bytes)) AS size,
       sum(rows) AS rows
FROM system.parts
WHERE active
GROUP BY database, table
ORDER BY sum(bytes) DESC
LIMIT 10;

结果:

system  text_log                34.15 GiB    9亿行
system  trace_log               11.41 GiB    5亿行
system  asynchronous_metric_log  9.36 GiB    347亿行
system  metric_log               7.75 GiB   3600万行
system  part_log                 4.65 GiB   6800万行
system  query_log                3.59 GiB   3800万行

几乎全是 ClickHouse 自己写的内部监控日志。业务数据加起来才几个 G。

第一步:立刻清理

TRUNCATE 把大头清空:

TRUNCATE TABLE system.text_log;
TRUNCATE TABLE system.trace_log;
TRUNCATE TABLE system.asynchronous_metric_log;
TRUNCATE TABLE system.metric_log;
TRUNCATE TABLE system.part_log;
TRUNCATE TABLE system.processors_profile_log;
-- query_log 可以选择保留,用于事后排查
TRUNCATE TABLE system.latency_log;

query_log 是”这个 ClickHouse 都处理过什么 SQL”的记录,日常排查很有用,多数情况留着。

清完之后:

SYSTEM FLUSH LOGS;

再查一次磁盘:

du -sh /var/lib/clickhouse/data/system/*

空间没立刻回收是正常的。因为:

  • MergeTree 的 parts 只是标记删除,等 merge
  • 文件系统 cache
  • delete_from_disk 有 TTL

可以强制一下:

OPTIMIZE TABLE system.query_log FINAL;

或者最粗暴:

sudo systemctl restart clickhouse-server

启动时会跳过被标记删除的 parts。

第二步:从根源关掉不需要的日志

清了以后不管,几周后又长回来。要真省心就编辑 config,把不用的日志表直接关掉。

编辑:

sudo nano /etc/clickhouse-server/config.d/logs.xml

内容:

<clickhouse>
    <!-- 关掉巨吃磁盘的三个 -->
    <text_log remove="1"/>
    <trace_log remove="1"/>
    <asynchronous_metric_log remove="1"/>
    <metric_log remove="1"/>
    <part_log remove="1"/>
    <processors_profile_log remove="1"/>

    <!-- query_log 保留,但缩短 TTL -->
    <query_log>
        <database>system</database>
        <table>query_log</table>
        <partition_by>toYYYYMM(event_date)</partition_by>
        <ttl>event_date + INTERVAL 7 DAY DELETE</ttl>
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
    </query_log>
</clickhouse>
  • remove="1" 直接不启用这类表
  • <ttl> 让 ClickHouse 自动过期删除老数据

重启生效:

sudo systemctl restart clickhouse-server

为什么这些表会爆

asynchronous_metric_log 每秒都在采几百个指标,一天几千万行是正常的。trace_log 记录每个 query 的 profile 事件,非常细。这些表默认全开,对于开发/测试很有用,对生产就是纯磁盘杀手。

生产环境的经验:

  • 保留query_log(+ 7 天 TTL)
  • 可选保留query_thread_log 排查慢查询用
  • 关掉text_logtrace_logasynchronous_metric_logmetric_logpart_logprocessors_profile_log

如果需要采指标,用 Prometheus 拉 /metrics 接口,别依赖 ClickHouse 内部 metric_log

顺手加个磁盘水位报警

SELECT
    name,
    formatReadableSize(free_space) AS free,
    formatReadableSize(total_space) AS total,
    round(free_space / total_space * 100, 1) AS free_percent
FROM system.disks;

低于 20% 该发告警了。

一句话总结

ClickHouse 磁盘被吃是 system.*_log 表的锅。先 TRUNCATE 清空、再 config 里 remove="1" 关掉大部分、给 query_log 加个 TTL。生产上从第一天就该这么配。