セルフホストの Langfuse、SigNoz、ClickStack で動く ClickHouse® のための読み取り専用ディスク診断

ディスクはいっぱいになるのに、実際に保存しているデータはわずかしかありません。多くの場合、容量を使っているのは ClickHouse 自身のシステムログテーブル(system log tables)で、これらのテーブルにはデフォルトではサイズの上限がありません。diskvet はディスクを何が占めているかを示し、解決するための具体的なコマンドを出力します。自動で実行されるものは何もなく、コマンドはすべて自分で実行します。

無料、Apache-2.0、登録不要です。短いファイルが 2 つだけなので、実行前に中身を読めます。スクリプトが通信するのはお使いの 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         # 任意: 2 つのファイルがリリースと一致することを確認
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 にあります。

チェック項目

#チェック読み取り元レポートに出る典型的な対処
1TTL のないシステムログテーブルsystem.tables、system.partsTRUNCATE(50 GB を超える場合は 1 回限りのフラグファイルを併用)、レポートが生成する config.d 用の TTL 設定ファイル、削除すべき古い *_log_N のコピー
2ClickHouse テーブルのパーツ(part)以外が占めるディスク容量system.disks とすべてのパーツの比較Docker のログのローテーションと、ほかに確認すべき場所
3ディスク使用量とおおまかな予測system.disks、system.asynchronous_metric_log優先して解放すべきもの
41 日あたりの増加量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') を 1 回

決して読み取らないもの

  • お使いのテーブルの行:それらのテーブルに対する FROM や JOIN、テーブル関数、dictGet は一切使いません。これはテストスイートで保証しています。
  • system.query_log、クエリ本文、ミューテーションのコマンド、エラーメッセージ

ローカルのレポートには実際のデータベース名とテーブル名が表示されます。対処を実行するときに必要だからです。レポートはお使いのマシンの外には出ません。

安全に実行する 2 つの方法

  • 既存のユーザーを使う。クエリは 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 のディスクがいっぱいになる原因と対処法

問題を確認するための読み取り専用クエリ 1 つ、今すぐ容量を空ける方法、そして既知の落とし穴を避けながら再発を防ぐ方法をまとめています。ガイド内のコマンドはすべて ClickHouse 24.8、25.12、26.9 で実際に実行して確認しています。ガイドに沿って作業するのに diskvet は必要ありません。

1 時間ごとの診断:10 月に無料ベータ

スクリプトは無料で、今後も無料のままです。ただ、1 回の実行だけでは、ディスクが実際にいつ満杯になるかはわかりません。その部分を補うものとして、現在次の機能を開発しています。

  • 1 時間ごとのスナップショット。内容は sh diskvet.sh --print-payload が出力する JSON そのもので、それ以外は含みません。
  • ディスクが満杯になる前に届くメール通知(状態が変わったときのみ)
  • スナップショットが届かなくなったときのアラート
  • 毎週月曜日の短いレポート

お使いの環境で何かをホストする必要も、ポートを開ける必要もありません。サーバーから署名付きの小さなスナップショットを外部へ送信するだけで、外部から接続されることはありません。ホスト名、IP アドレス、ユーザー名、クエリ本文、エラーは一切送信しません。お使いのテーブル名は、ソルト付きハッシュとしてのみサーバーの外に出ます。

参加したい場合は、スレッド「Early access」(ディスカッション #1)に、お使いの ClickHouse がどの環境で動いているかと、ディスクのおおよそのサイズをコメントしてください。日本語で書き込んでも構いませんが、返信は英語になる場合があります。ベータの受付が始まったら、そのスレッドで返信します。公開スレッドなので、会社名やホスト名は書かないでください。

ベータ期間は 30 日間です。その後、1 時間ごとの診断は有料プランになりますが、スクリプトは引き続き無料のオープンソースです。カザフスタン国内のサーバーは、当面はローカルレポートのみの対応となります。

スクリプトが見逃している問題や、誤った対処を見つけたら、Issue を作成してください。それが何よりの助けになります。日本語で書いても構いませんが、返信は英語になる場合があります。