mcpField
A
analyzing-schema-change-storage-risk

analyzing-schema-change-storage-risk

github.com/cockroachlabsデータ・データベース23127 回インストール14 週間前に更新
リポジトリ

analyzing-schema-change-storage-risk について

CockroachDBのオンラインスキーマ変更前に、ストアごとに必要な空き容量を見積もるスキルです。レンジとインデックスのサイズを使い、空き容量を操作別の保守的な目標と比較します。

主な機能

  1. 01ストアごとの最小空き容量を確認
  2. 02テーブルとインデックスのサイズを推定
  3. 03操作別の容量目標を設定
  4. 04一時停止中のスキーマ変更ジョブを特定
  5. 05レンジ統計の制約を考慮

活用シーン

  1. 01大規模インデックス作成前の空き容量評価
  2. 02大規模テーブルのALTER PRIMARY KEY計画
  3. 03クエリ結果のマテリアライズ前の容量確認
  4. 04容量不足で停止したスキーマ変更の調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/cockroachlabs/cockroachdb-skills --skill analyzing-schema-change-storage-risk

インストール後、Claude Code で/analyzing-schema-change-storage-riskを入力して読み込まれたか確認します。

詳細

スキーマ変更に伴うストレージリスクの分析

オンラインスキーマ変更を安全に実行するために必要なストレージの余裕を推定します。 公式ガイダンスを反映しています。 一部の操作では、スキーマ変更の実行中に、影響を受ける テーブルまたはインデックスのサイズの最大 3 倍が一時的に必要になる場合があります。

継続的なレンジ分布の監視については、 analyzing-range-distributionを参照してください。

このスキルを使用するタイミング

インデックスが大きい(インデックスあたり数 GB、またはインデックスあたりのレンジ数が多い)テーブルに対して、次のいずれかの操作を実行する前に、簡易的な見積もりを行ってください。

  • CREATE INDEX
  • INDEX または UNIQUE を指定した ADD COLUMN
  • ALTER PRIMARY KEY
  • CREATE MATERIALIZED VIEW
  • CREATE TABLE AS
  • REFRESH MATERIALIZED VIEW
  • ALTER TABLE ... SET LOCALITY(ローカリティの変更によってデータが書き換えられる場合)

インデックスが小さい(キロバイトから数メガバイト程度)テーブルのストレージリスクはごくわずかで、見積もりは不要です。

背景

バックフィルで実際に必要となる一時領域はどのくらいですか?

正確な答えは操作によって異なります。

  • CREATE INDEX / ADD COLUMN ... UNIQUE:通常、新しいインデックスのサイズの約 1 倍が必要です。インデックス対象の列と主キーの列を、新しいインデックススパンに書き込みます。これは通常、テーブルのサイズのごく一部です。最悪の場合でも、必要な余裕はそのインデックス 1 つのサイズが上限となります。
  • ALTER PRIMARY KEY:主インデックスと、定義が古い PK に依存するセカンダリインデックスを書き換えます。古いデータは GC が行われるまで残るため、変更中のディスク使用量のピークは、テーブルのサイズとほぼ同じ分だけ増える可能性があります。
  • すべての一括取り込みバックフィル:Pebble がコンパクションを実行し、GC が行われるまで、追加の MVCC バージョンとコンパクション前の SST によるオーバーヘッドが発生します。

公式ドキュメントでは、これらを単一の保守的な推奨値にまとめています。 空き領域として、影響を受けるテーブルまたはインデックスのサイズの最大 3 倍を確保してください。 この数値は安全上の上限であり、正確な予測値ではありません。ほとんどの CREATE INDEX 操作では実際のコストははるかに小さくなりますが、大きなテーブルに対する ALTER PRIMARY KEY では妥当な目安です。

バックフィル中にクラスターのディスク容量が不足するとどうなりますか?

バックフィルでは AddSSTable を介してデータを一括取り込みします。AddSSTable は各取り込みの前に、ストアごとの残り容量を確認します。残り容量の割合が kv.bulk_io_write.min_capacity_remaining_fraction(デフォルトは 0.05、つまり 5%)を下回ると、取り込みは InsufficientSpaceError で拒否されます。旧式のスキーマ変更機構と宣言型スキーマ変更機構は、どちらもこのエラーをジョブの一時停止リクエストに変換するため、クラスターが機能不全に陥る代わりに、スキーマ変更が停止します。再開するには、未使用のインデックスの削除やストレージの拡張などで空き領域を確保し、一時停止中のジョブを再開してください。

これは事後対応型の安全策であり、計画のためのツールではありません。この安全策が作動する頃には、影響を受けるストアでのフォアグラウンド書き込みがすでに不安定になっている可能性があります。

容量の見積もり

ステップ 1 — ストアごとの空き領域を確認する

スキーマ変更の上限を決めるのは、クラスター全体の空き領域ではなく、ストアごとの空き領域の最小値です(レプリカは複数のノードに分散されます)。

本番環境で安全に使用できる SQL ビューでは、ストアごとの容量を公開していません。DB コンソールの Overview → Storage ページ(ストアごとの使用量で並べ替え可能)を使用するか、ノードごとの Prometheus エンドポイントからデータを取得し、最小の capacity_available を確認してください。

curl -ks https://<node>:8080/_status/vars | grep -E '^capacity( |_used|_available)'
ステップ 2 — 影響を受けるテーブル/インデックスのサイズを見積もる

ドキュメントで推奨されている形式の SHOW RANGES を使用します。

SHOW RANGES FROM TABLE <table> WITH DETAILS, KEYS, INDEXES;

出力にはレンジごとに 1 行が含まれ、range_size_mb と index_name が示されます。容量計画で重要となるインデックスごとの合計を得るには、インデックス単位で集計してください。

WITH r AS (SHOW RANGES FROM TABLE <table> WITH DETAILS, KEYS, INDEXES)
SELECT
  index_name,
  COUNT(*)                              AS range_count,
  ROUND(SUM(range_size_mb), 2)          AS index_size_mb,
  ROUND(SUM(range_size_mb) / 1024, 2)   AS index_size_gb
FROM r
GROUP BY index_name
ORDER BY index_size_mb DESC;
ステップ 3 — 操作と比較する
操作保守的な空き容量の目標(ストアごと)
CREATE INDEX / ADD COLUMN ... UNIQUE新しいインデックスのサイズ(インデックス対象列と PK 列)の最大 3 倍。
ALTER PRIMARY KEYテーブルのサイズ(ステップ 2 の関連インデックスの合計)の最大 3 倍。
CREATE MATERIALIZED VIEW / CREATE TABLE ASマテリアライズされた結果の予想サイズの最大 3 倍。

新しいインデックスはまだ存在しないため、比較可能な既存のインデックス(例:似た型の列を対象とするインデックス)または主インデックスにおけるソース列の寄与分から推定します。

ステップ 1 で確認した最小の空き容量が目標を十分に上回っていれば、その操作は安全に実行できます。空き容量が目標に近い場合は、DDL を実行する前に空き容量を確保してください(未使用のインデックスを削除する、ストレージを拡張するなど)。

運用上の注意

  • SHOW RANGES ... WITH DETAILS は負荷が高いコマンドです。 スパンの統計をオンデマンドで計算します。必ず特定のテーブルを対象にし、クラスター全体では実行しないでください。数千のレンジがあるテーブルでは、メンテナンス時間帯に実行することをおすすめします。
  • ディスクだけでなくジョブも監視してください。 バックフィルが InsufficientSpaceError で一時停止した場合は、影響を受けたストアのディスク容量を確保してから、一時停止中のスキーマ変更ジョブを再開してください。次のコマンドで確認します。
    WITH j AS (SHOW JOBS)
    SELECT job_id, status, error
    FROM j
    WHERE job_type = 'SCHEMA CHANGE' AND status = 'paused';
    
  • まず未使用のインデックスを削除してください。 大規模なバックフィルの前に余裕を確保する方法として、crdb_internal.index_usage_statistics で未使用と示されたインデックスを削除するのが最も安価なことがよくあります(ドキュメントによると、これは本番環境で安全に使用できる 12 個の crdb_internal ビューの 1 つです)。
  • 統計には遅延があります。 range_size_mb は概算で、実際のディスク使用量との間に遅れが生じる場合があります。推定値は正確な数値ではなく、保守的な目安として扱ってください。

参考資料

関連スキル

コメント