すべてのプロダクト
Search
ドキュメントセンター

PolarDB:pg_squeeze (表領域の再編成)

最終更新日:Jun 12, 2026

頻繁な UPDATE および DELETE 操作は、テーブルの肥大化としても知られる著しい断片化を引き起こす可能性があります。これにより、ストレージ領域が無駄になり、クエリパフォーマンスが低下します。pg_squeeze 拡張機能は、オンラインでテーブルを再編成することにより、この肥大化した領域を自動的に再利用します。論理デコーディングを使用して、書き込みパフォーマンスへの影響を最小限に抑えながらデータ変更をキャプチャし、サーバー上で自動的に実行されます。これにより、サービスを中断することなく、テーブル構造を継続的に最適化し、データベースパフォーマンスを向上させ、領域使用率を高めることができます。

pg_repack との比較

pg_squeezepg_repack は、どちらもテーブルの肥大化を管理するために使用される一般的な拡張機能です。pg_repack の代替として、pg_squeeze はその基盤となる仕組みと運用アプローチが異なります。ユースケースに最も適したものを選択してください。

項目

pg_squeeze

pg_repack

仕組み

論理デコーディング:レプリケーションスロットを使用して、WAL からのデータ変更を非同期にキャプチャします。

トリガー:ソーステーブルにトリガーを作成して、DML 操作を同期的にキャプチャします。

書き込みパフォーマンスへの影響

最小限です。変更のキャプチャは非同期プロセスであり、ソーステーブルの書き込みパフォーマンスへの影響は限定的です。

大きいです。各 DML 操作が追加の書き込みを発生させ、高い同時実行性の下ではボトルネックになる可能性があります。

リソース消費

1 つのレプリケーションスロットを消費します。コンパクションタスクが遅いか失敗した場合、WAL ファイルが蓄積され、ストレージ領域を消費する可能性があります。

トリガーは、高い同時実行性の下で CPU オーバーヘッドを増加させます。変更を記録するために追加のログテーブルが必要です。

運用上の複雑さ

タスクの失敗によるディスク領域の枯渇を防ぐために、レプリケーションスロットの状態と WAL ストレージを監視する必要があります。

スキーマ変更やデータ移行後もトリガーが正しく機能することを確認するために、トリガーを管理する必要があります。

クイックスタート

このセクションでは、テーブルの自動コンパクションタスクをインストール、設定、有効化するまでの全プロセスを説明します。

ステップ 1:クラスターパラメーターの設定

  1. PolarDB コンソールにログインします。クラスター ページで、対象のクラスターを見つけてその ID をクリックします。

  2. 左側のナビゲーションウィンドウで、設定と管理 > パラメーター を選択します。

  3. パラメーター ページで、次のパラメーターを変更します:

    • wal_levellogical に設定します。これは論理デコーディングを使用するための前提条件であり、WAL の生成がわずかに増加します。

    • max_replication_slots:十分なスロットが利用可能であることを確認します。pg_squeeze は、有効化された各データベースで少なくとも 1 + squeeze.workers_per_database 個のレプリケーションスロットを必要とします。現在の値を少なくとも 2 増やすことを推奨します (例:10 から 12 へ)。

    • shared_preload_libraries:既存の値に ,pg_squeeze を追加します。例えば、元の値が pg_stat_statements の場合、pg_stat_statements,pg_squeeze に変更します。

  4. パラメーター設定が有効になるまで、クラスターが再起動するのを待ちます。

ステップ 2:拡張機能のインストールと起動

表領域を再編成したい対象のデータベースで pg_squeeze を有効にします。

  1. 対象のデータベースに接続します。

  2. 次の SQL ステートメントを実行して拡張機能を作成し、スケジューラワーカーを起動します。このプロセスは、squeeze.tables の設定に基づいて定期的にコンパクションタスクをチェックし、開始します。

    -- 対象のデータベースに拡張機能を作成
    CREATE EXTENSION pg_squeeze;
    
    -- バックグラウンドスケジューラプロセスを開始
    -- この操作は、pg_squeeze を使用する各データベースで一度だけ実行する必要があります
    SELECT squeeze.start_worker();
  3. (オプション) 次の SQL ステートメントを実行して、バックグラウンドプロセスが正常に開始されたことを確認します。application_namesqueeze scheduler のプロセスが表示されれば、プロセスは正常に開始されています。

    SELECT * FROM pg_stat_activity WHERE application_name LIKE 'squeeze%';

ステップ 3:処理対象テーブルの設定

pg_squeeze が管理するテーブルを指定し、それらのチェックおよびコンパクションポリシーを定義します。

  1. テーブルに レプリカ ID があることを確認しますpg_squeeze は、古いテーブルと新しいテーブルの間で行の変更を照合するための一意の識別子を必要とします。プライマリキーは自動的に レプリカ ID として使用されます。

    • 確認:\d+ your_table_name コマンドを使用して、テーブルの レプリカ ID プロパティが DEFAULT または FULL であるかを確認します。

    • 設定:テーブルにプライマリキーがないが、一意なインデックス (例:your_table_uidx) がある場合、次のコマンドを実行してそれを レプリカ ID として設定できます。

      ALTER TABLE your_table_name REPLICA IDENTITY USING INDEX your_table_uidx;
  2. テーブルを squeeze.tables に登録します:テーブル情報とスケジューリングポリシーを squeeze.tables 設定テーブルに挿入します。schedule フィールドは、Cron 式に似た形式でチェック時間を定義します。

    -- 例 1:毎日午前 2:30 に public.foo テーブルをチェック
    INSERT INTO squeeze.tables (tabschema, tabname, schedule)
    VALUES ('public', 'foo', ROW(ARRAY[30], ARRAY[2], NULL, NULL, NULL)::squeeze.schedule);
    
    -- 例 2:毎週日曜日の午前 4:00 に public.bar テーブルをチェックし、コンパクション後にプライマリキーでソート
    INSERT INTO squeeze.tables (tabschema, tabname, schedule, clustering_index)
    VALUES ('public', 'bar', ROW(ARRAY[0], ARRAY[4], NULL, NULL, ARRAY[0])::squeeze.schedule, 'bar_pkey');

    schedule フィールドの構造は (分, 時, 日, 月, 曜日) です。NULL は任意の値を示します。その他の設定オプションについては、「付録:squeeze.tables 設定テーブル」をご参照ください。

ステップ 4:モニタリングと検証

コンパクションタスクが期待どおりに実行されているか、成功または失敗したかを確認します。pg_squeeze が提供するビューとテーブルをクエリすることで、タスクの状態を監視できます。

-- 現在のデータベースでアクティブなコンパクションタスクを表示
SELECT * FROM squeeze.get_active_workers();

-- 最新 10 件の成功したコンパクション履歴レコードを表示
SELECT * FROM squeeze.log ORDER BY finished DESC LIMIT 10;

-- 失敗したコンパクションレコードとその原因を表示
SELECT * FROM squeeze.errors;

ステップ 5:(オプション) 定期コンパクションの無効化

特定のテーブルが定期的なコンパクションを必要としなくなった場合は、squeeze.tables テーブルから対応する行を削除するだけです。

DELETE FROM squeeze.tables WHERE tabschema = 'public' AND tabname = 'foo';

手動コンパクション

定期的な実行に加えて、squeeze.tables に登録せずに、任意のテーブルに対してオンデマンドのコンパクションを手動でトリガーできます。これは、即時の一回限りのコンパクションに便利です。

squeeze.squeeze_table() 関数を使用して、手動コンパクションタスクを開始します。

-- public.pgbench_accounts テーブルに対してデフォルトのコンパクションタスクを開始
SELECT squeeze.squeeze_table('public', 'pgbench_accounts');

-- コンパクションタスクを開始し、完了時にテーブルをプライマリキー (pgbench_accounts_pkey) で物理的にソート
SELECT squeeze.squeeze_table('public', 'pgbench_accounts', 'pgbench_accounts_pkey');
説明

squeeze.squeeze_table 関数はトランザクションではありません。コンパクションを実行するためのバックグラウンドワーカープロセスを開始するだけで、すぐに戻ります。この関数を呼び出したトランザクションをロールバックしても、すでに開始されているバックグラウンドのコンパクションタスクは停止しません。

詳細設定

同時実行数とロック動作の調整

ビジネスワークロードに影響を与えないように、コンパクションプロセスを微調整します。squeeze.max_xlock_time パラメーターを設定することで、コンパクションの最終フェーズで排他ロックが保持される最大時間を制限し、サービスでの長時間のブロックを防ぐことができます。

-- 最大排他ロック保持時間を 100 ミリ秒に設定
SET squeeze.max_xlock_time TO 100;

ロック保持時間がこの制限を超えた場合、pg_squeeze はロックを解放し、その間に発生したデータ変更を処理してから、再度ロックの取得を試みます。繰り返しの試行がタイムアウトした場合、タスクはエラーで失敗します。ロックのタイムアウトが頻繁に発生する場合は、まずタスクをオフピーク時間帯にスケジュールしてみてください。それが不可能な場合は、このパラメーター値を増やすことを検討してください。

同時ワーカーの設定

多くのテーブルを同時に処理する必要がある場合、ワーカープロセスの数を増やしてコンパクションスループットを向上させることができます。squeeze.workers_per_database パラメーターを 1 より大きい値に設定すると、単一のデータベース内で複数のテーブルの並列コンパクションタスクが可能になります。

-- データベースごとに最大 2 つの同時コンパクションワーカープロセスを許可
SET squeeze.workers_per_database = 2;
説明

この設定は、pg_squeeze 拡張機能を使用しているすべてのデータベースに影響します。クラスター内のワーカーの総数 (スケジューラワーカーを含む) は、max_worker_processes パラメーターの値を超えることはできません。

付録:squeeze.tables 設定テーブル

squeeze.tables テーブルは、pg_squeeze のコア設定ハブです。このテーブルを使用して、テーブルを登録し、その処理ポリシーを定義します。

パラメーター

説明

デフォルト

推奨事項

tabschema

name

テーブルのスキーマ名。

-

-

tabname

name

テーブルの名前。

-

-

schedule

squeeze.schedule

タスクチェックのスケジュール。(分, 時, 日, 月, 曜日) の形式。

-

ビジネスのオフピーク時間または低トラフィックのウィンドウに合わせて設定します。例えば、毎日午前 2:30 に実行する場合:ROW(ARRAY[30], ARRAY[2], NULL, NULL, NULL)::squeeze.schedule

free_space_extra

integer

fillfactor によって予約された領域を超える、コンパクションをトリガーするために必要な追加の肥大化率。

50

書き込みが多い OLTP テーブルの場合、この値を低くする (例:30) ことを検討し、より頻繁に小さなバッチで領域を再利用します。

min_size

integer

最小テーブルサイズ (MB)。これより小さいテーブルは処理されません。

8

小さなテーブルでの不要な操作を避けるために、デフォルト値を維持します。

vacuum_max_age

interval

最後の VACUUM からの最大時間で、この間は空き領域マップ (FSM) が有効と見なされます。

'1 hour'

デフォルト値を維持します。この時間を超えると、pg_squeeze はより詳細な分析を実行して、コンパクションが必要かどうかを判断します。

max_retry

integer

初期コンパクションが失敗した場合に許可される最大リトライ回数。

0

DDL 変更やその他の理由でテーブルのコンパクションが頻繁に失敗する場合、この値を増やす (例:2) ことを検討し、タスクの成功率を向上させます。

clustering_index

name

既存のインデックスを指定します。コンパクション後、テーブル内のデータは、CLUSTER コマンドと同様に、このインデックスのキーに従って物理的にソートされます。

NULL

範囲で頻繁にクエリされるテーブルの場合、プライマリキーまたはコアクエリインデックスをクラスタリングインデックスとして設定することを検討してください。これにより、クエリパフォーマンスが大幅に向上する可能性があります。

rel_tablespace

name

コンパクション後にテーブルが移動するターゲット表領域を指定します。

NULL

表領域の移行シナリオで使用されます。NULL の場合、テーブルは元の表領域に残ります。

ind_tablespaces

name[]

インデックスの表領域マッピングを指定するために使用される 2 次元配列。

NULL

インデックス表領域の移行に使用されます。

skip_analyze

boolean

コンパクション後に ANALYZE コマンドをスキップするかどうかを指定します。

false

これを false のままにすることを推奨します。コンパクションはテーブルのデータ分布を変更するため、ANALYZE を実行すると、オプティマイザーが正確な実行計画を生成するのに役立ちます。