db-storage-bloat について
データベースのストレージ保守と稼働状態を評価する監査スキルです。PostgreSQLのVACUUM、トランザクションIDのラップアラウンド、ワイドカラム型のトゥームストーンを静的チェックと実稼働統計で調べます。
主な機能
- 01VACUUMとautovacuumの状態を確認
- 02トランザクションIDのラップアラウンドを評価
- 03トゥームストーンによる読み取り劣化を検出
- 04カタログと統計情報のクエリを使用
- 05更新頻度の高いテーブル設定を確認
活用シーン
- 01PostgreSQLのテーブル膨張を調査
- 02トランザクションIDの余裕を確認
- 03autovacuum設定をレビュー
- 04トゥームストーンの多い処理を評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hainrixz/ claude-db --skill db-storage-bloatインストール後、Claude Code で/db-storage-bloatを入力して読み込まれたか確認します。
詳細
db-storage-bloat (M18)
ストレージの運用性を保つことは、データベースの高速性と長期的な稼働を支えます。これは Performance & Scale(軸
performance)に関するもので、リレーショナルの Almacenamiento w12(M22/M20/M21 と共有)と、
ワイドカラムプロファイルの Tombstones カテゴリに関係します。致命的なケースである TXID wraparound が発生すると、
Postgres のシャットダウンを強いられる可能性があるため、差し迫っている場合は severity:5 の上限を適用します。
チェック内容
- VACUUM/autovacuum の健全性 — 変更頻度の高いテーブルで autovacuum が無効化されている、または設定が不適切であること、デッドタプルの蓄積、テーブルやインデックスの肥大化によるサイズ増加とスキャンの低速化。
- TXID wraparound —
age(datfrozenxid)(またはテーブル単位のrelfrozenxid)がautovacuum_freeze_max_ageまたは 20 億の上限に近づいていること。差し迫った wraparound はseverity:5、fail(perf)ですが、実稼働中の経過年齢を示す証拠がある場合に限ります。静的解析ではneeds_apiを促すにとどめます。 - Tombstones(ワイドカラム) — Cassandra/Scylla で大量の削除や TTL の頻繁な変更により tombstone が生成され、読み取り性能が低下する状態(
tombstone_warn_thresholdの対象領域)。
スコア/軸
performance のみが対象です(リレーショナルの Almacenamiento w12、ワイドカラムプロファイルの Tombstones)。
Tier-0(静的解析)
M18 のほとんどは実行時の状態です。静的解析では、autovacuum を無効にする DDL/設定
(autovacuum_enabled = false、積極的な fillfactor)、削除/TTL が多いアクセスパターン、ワイドカラムで削除の多いデータモデリングを検出します。デッドタプル数、実際の肥大化、frozen-xid の経過年齢、tombstone の件数はすべて稼働中の DB が必要なため、Tier-0 では status: needs_api とします(検出できない状態を問題なしとして扱うことはありません)。
Tier-1/2(検証クエリ、Postgres)
-- TXID wraparound headroom (Tier-1):
SELECT datname, age(datfrozenxid) AS xid_age,
current_setting('autovacuum_freeze_max_age')::int AS freeze_max
FROM pg_database ORDER BY age(datfrozenxid) DESC;
-- dead tuples + last autovacuum (Tier-2):
SELECT relname, n_dead_tup, n_live_tup, last_autovacuum
FROM pg_stat_user_tables ORDER BY n_dead_tup DESC LIMIT 20;
メソッドは query_stat です。xid_age が freeze_max(または 2e9 の上限)に近い場合、wraparound が established と確認され、上限が適用されます。n_dead_tup が多く、last_autovacuum が古いか NULL の場合、肥大化が established と確認されます。継続的な統計情報がなければ、肥大化は directional のままです。
検出結果
schema/finding.schema.json に従って検出結果を出力します。例:
M18.db.txid_wraparound_imminent—xid_ageが上限に近づいている(severity:5、fail、軸performance、信頼度は Tier-1 のみestablished/Tier-0 ではneeds_api、fixable: advisory— 積極的なVACUUM (FREEZE))。M18.events.autovacuum_disabled— 変更頻度の高いテーブルで autovacuum が無効になっている(severity:3、warn、 DDL からestablished、fixable: proposed)。M18.events.dead_tuple_bloat— デッドタプルの比率が高い(severity:3、warn、Tier-2 ではestablished/needs_api、fixable: advisory)。
各検出結果では、evidence.observed に設定/DDL の行、またはカタログ/統計情報の行をそのまま引用します。
verification.reproduce は $DATABASE_URL を参照する上記のクエリです。expected_impact は範囲と信頼度タグを付けて示します(単独の % 値は不可)。
正確性について
- wraparound の重要度 5 には 稼働中の
age()の証拠が必要です。ファイルだけから差し迫っていると判断してはなりません。接続がない場合はneeds_apiを出力します。これは上限を適用しません。 - 「肥大化」の一部は通常の安定稼働に必要な余裕です。変更パターンまたは測定したデッドタプル比率に照らしてのみ警告し、ファイルのみでの判定は
directionalとします。 - 観測できないデッドタプルの割合や wraparound までの日数を引用してはなりません。規模は範囲でのみ示します。定期的なメンテナンスによる修正(
VACUUM、autovacuum の調整)はproposed/advisoryとします。
対処方法 — 更新を HOT に保つ
更新頻度の高いテーブルでは、FILLFACTOR を下げる(例:デフォルトの 100/90 から 70 にする)ことで各ページに空き領域が残り、UPDATE が新しい行バージョンを HOT(Heap-Only Tuple)更新として同じページに配置できます。これにより新しいインデックスエントリの書き込みが不要になり、インデックスの書き込み増幅が抑えられ、肥大化の進行が遅くなります。HOT が実行されるのは、インデックス対象の列が変更されず、ページに空きがある場合のみです。そのため、FILLFACTOR を下げ、変更頻度の高い列にインデックスを付けすぎないことが対策となります。これは上記の autovacuum/肥大化の検出結果に対する前向きな対応策です。FILLFACTOR の変更が書き換えを発生させるのは、その後の更新時に限られるため、fixable: proposed として出力します。