自托管 Langfuse、SigNoz 和 ClickStack 中 ClickHouse® 的只读磁盘体检
磁盘满了,可你自己的数据并不多。空间通常被 ClickHouse 自带的系统日志表(system log tables)占掉,这些表默认没有大小上限。diskvet 会告诉你磁盘空间被什么占用,并输出具体的修复命令。它不会自动执行任何操作,每条命令都由你自己运行。
免费,Apache-2.0 许可,无需注册。只有两个短小的文件,运行前可以先读一遍。脚本只和你的 ClickHouse 通信,不会把任何数据发到别处。
典型案例
system.trace_log占了 66.86 GiB,而 Langfuse 自己的表只有约 51 MiB(langfuse#13123);- 系统日志 80+ GB,而遥测数据不到 500 MB(SigNoz#12050);
- 一个 10 Gi 的卷 10 天就满了(ClickStack-helm-charts#275)。
主要的修法大家都知道:对日志表执行 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.parts | TRUNCATE(超过 50 GB 时配合一次性的标志文件)、生成好的 config.d TTL 配置文件、需要删除的 *_log_N 旧表 |
| 2 | ClickHouse 表数据片段(part)之外的磁盘占用 | system.disks 对比所有数据片段 | Docker 日志轮转,以及其他值得排查的位置 |
| 3 | 磁盘使用率和粗略预测 | system.disks、system.asynchronous_metric_log | 优先释放哪些空间 |
| 4 | 每日增长 | system.part_log | 24 小时内哪张表写入最多 |
| 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,这是你能提供的最大帮助。可以用中文写,但回复可能是英文。