自托管 Langfuse、SigNoz 和 ClickStack 中 ClickHouse® 的只读磁盘体检

磁盘满了,可你自己的数据并不多。空间通常被 ClickHouse 自带的系统日志表(system log tables)占掉,这些表默认没有大小上限。diskvet 会告诉你磁盘空间被什么占用,并输出具体的修复命令。它不会自动执行任何操作,每条命令都由你自己运行。

免费,Apache-2.0 许可,无需注册。只有两个短小的文件,运行前可以先读一遍。脚本只和你的 ClickHouse 通信,不会把任何数据发到别处。

典型案例

主要的修法大家都知道:对日志表执行 TRUNCATE,再加上 TTL(生存时间)。报告还会指出这个修法在实践中会踩到的坑:TRUNCATE 的 50 GB 限制、重启后留下的 *_log_N 旧表、opentelemetry_span_log 的特殊配置、没有轮转的 Docker 日志,以及已经删除但仍占着空间的行。

快速开始:用 docker compose 部署的 Langfuse(30 秒)

在运行 Langfuse docker-compose.yml 的机器上:

cd langfuse                     # Langfuse 的 docker-compose.yml 所在目录
curl -fsSLO https://github.com/Protemir/diskvet/releases/latest/download/diskvet.sh
curl -fsSLO https://github.com/Protemir/diskvet/releases/latest/download/checks.sql
curl -fsSLO https://github.com/Protemir/diskvet/releases/latest/download/SHA256SUMS
sha256sum -c SHA256SUMS         # 可选: 校验两个文件与发布版本一致
less checks.sql                 # 先读一遍: 只有针对 system.* 的 SELECT

sh diskvet.sh report --docker auto > report.md

--docker auto 会自己找到 ClickHouse 容器,并在容器内运行 clickhouse-client,所以宿主机上既不需要装客户端,也不需要开放端口。不加 --user 时,它使用容器自身的 CLICKHOUSE_USER / CLICKHOUSE_PASSWORD,密码不会离开容器。

其他连接方式:

sh diskvet.sh report --docker signoz-clickhouse                          # 按名称指定容器
sh diskvet.sh report --host 127.0.0.1 --user diskvet --password '...'   # 本机的 clickhouse-client

需要 POSIX sh、awk、sed、od、date,以及 docker 或 clickhouse-client。不需要 jq,也不需要 Python。脚本输出的报告是英文的。最新版本见 GitHub Releases。

检查项

#检查项读取来源报告中的典型修复
1没有 TTL 的系统日志system.tables、system.partsTRUNCATE(超过 50 GB 时配合一次性的标志文件)、生成好的 config.d TTL 配置文件、需要删除的 *_log_N 旧表
2ClickHouse 表数据片段(part)之外的磁盘占用system.disks 对比所有数据片段Docker 日志轮转,以及其他值得排查的位置
3磁盘使用率和粗略预测system.disks、system.asynchronous_metric_log优先释放哪些空间
4每日增长system.part_log24 小时内哪张表写入最多
5数据片段过多system.parts、system.merge_tree_settings、system.events距离该表的插入限制还有多远
6非活动(inactive)和已分离(detached)的数据片段system.parts、system.detached_parts卡住的数据片段、DROP DETACHED PART
7已删除的行和卡住的变更(mutation)system.parts、system.mutations针对具体分区(partition)的 APPLY DELETED MASK、KILL MUTATION

每项检查给出 OK、INFO、WARN 或 CRITICAL 结论,阈值见 README。每条修复建议都会注明安全性以及是否需要重启。某项检查的查询失败时,会显示 NOT_RUN 和原因,其他检查照常运行。

读取什么,绝不读取什么

会读取

  • 以下系统表中的元数据:system.tables、system.parts、system.disks、system.detached_parts、system.merge_tree_settings、system.mutations、system.part_log、system.asynchronous_metric_log、system.asynchronous_metrics、system.events;
  • 有权限时读取 system.server_settings(仅读取 max_table_size_to_drop 一项);
  • 一条探测查询 SELECT getSetting('readonly'),用来确认会话是只读的。

绝不读取

  • 你自己表里的数据行:不对它们做 FROM 或 JOIN,不用表函数,也不用 dictGet,测试套件会强制检查这一点;
  • system.query_log、查询文本、变更命令和错误文本。

本地报告会显示真实的库名和表名,因为执行修复时要用到它们。报告只保存在你的机器上。

两种安全的运行方式

  • 使用现有用户。查询以 readonly=2 运行,并设有资源限制(30 秒、10,000 行、2 个线程、500 MB)。如果服务器不允许该用户进入只读模式,脚本会直接停止,不运行任何检查。
  • 使用专用用户,适合需要通过安全审查的场景:只授予上述系统表的最小权限,无法访问业务数据。具体 SQL 见 README。

已在官方原版 clickhouse/clickhouse-server 镜像 24.1、24.8、25.12 和 26.9 上测试,测试环境模拟了 Langfuse 和 SigNoz 的部署。尚未测试:带副本的集群、Kubernetes、对象存储上的磁盘、macOS。

想手动修复?

自托管 Langfuse 和 SigNoz:ClickHouse 磁盘被占满的原因与解决方法

内容包括:如何用一条只读查询确认问题、如何立即释放空间,以及如何避开已知的坑、防止问题复发。其中每条命令都在 ClickHouse 24.8、25.12 和 26.9 上实际运行过。照着做不需要 diskvet。

每小时体检:10 月免费内测

脚本免费,而且会一直免费。但单次运行无法告诉你磁盘究竟什么时候会满。这正是我现在在做的部分:

  • 每小时一次快照:内容就是 sh diskvet.sh --print-payload 打印的那段 JSON,没有别的;
  • 在磁盘写满之前发邮件提醒,而且只在状态变化时发送;
  • 快照不再送达时发出告警;
  • 每周一发一份简短报告。

你不需要自己部署任何服务,也不需要开放端口:由你的服务器主动向外发送一份签名的小快照,没有任何外部连接进来。主机名、IP、用户名、查询文本和错误信息永远不会发送;你自己的表名只会以加盐哈希的形式离开服务器。

想参加?到 Early access 讨论帖(#1)留言,说明你的 ClickHouse 运行在什么环境里、磁盘大概有多大。可以用中文留言,但回复可能是英文。内测开放时,你会在那里收到回复。请不要在那里写公司名或主机名:这是公开讨论帖。

内测为期 30 天,之后每小时体检将转为付费套餐,脚本本身仍然免费、开源。位于哈萨克斯坦的服务器目前只能使用本地报告。

发现脚本漏掉的问题,或者修复建议有误?请提交 issue,这是你能提供的最大帮助。可以用中文写,但回复可能是英文。