頻繁な UPDATE および DELETE 操作は、テーブルの肥大化としても知られる著しい断片化を引き起こす可能性があります。これにより、ストレージ領域が無駄になり、クエリパフォーマンスが低下します。pg_squeeze 拡張機能は、オンラインでテーブルを再編成することにより、この肥大化した領域を自動的に再利用します。論理デコーディングを使用して、書き込みパフォーマンスへの影響を最小限に抑えながらデータ変更をキャプチャし、サーバー上で自動的に実行されます。これにより、サービスを中断することなく、テーブル構造を継続的に最適化し、データベースパフォーマンスを向上させ、領域使用率を高めることができます。
適用範囲
サポートされている PolarDB for PostgreSQL のバージョンは次のとおりです。
PostgreSQL 18 (マイナーカーネルバージョン 2.0.18.1.2.0 以降)
PostgreSQL 17 (マイナーカーネルバージョン 2.0.17.7.5.0 以降)
PostgreSQL 16 (マイナーカーネルバージョン 2.0.16.10.12.0 以降)
PostgreSQL 15 (マイナーカーネルバージョン 2.0.15.15.7.0 以降)
PostgreSQL 14 (マイナーカーネルバージョン 2.0.14.19.40.0 以降)
PolarDB コンソールで、または SHOW polardb_version; コマンドを実行して、マイナーカーネルバージョンを表示できます。ご利用のクラスターがこの要件を満たしていない場合は、マイナーカーネルバージョンをアップグレードしてください。
pg_repack との比較
pg_squeeze と pg_repack は、どちらもテーブルの肥大化を管理するために使用される一般的な拡張機能です。pg_repack の代替として、pg_squeeze はその基盤となる仕組みと運用アプローチが異なります。ユースケースに最も適したものを選択してください。
項目 | pg_squeeze | pg_repack |
仕組み | 論理デコーディング:レプリケーションスロットを使用して、WAL からのデータ変更を非同期にキャプチャします。 | トリガー:ソーステーブルにトリガーを作成して、DML 操作を同期的にキャプチャします。 |
書き込みパフォーマンスへの影響 | 最小限です。変更のキャプチャは非同期プロセスであり、ソーステーブルの書き込みパフォーマンスへの影響は限定的です。 | 大きいです。各 DML 操作が追加の書き込みを発生させ、高い同時実行性の下ではボトルネックになる可能性があります。 |
リソース消費 | 1 つのレプリケーションスロットを消費します。コンパクションタスクが遅いか失敗した場合、WAL ファイルが蓄積され、ストレージ領域を消費する可能性があります。 | トリガーは、高い同時実行性の下で CPU オーバーヘッドを増加させます。変更を記録するために追加のログテーブルが必要です。 |
運用上の複雑さ | タスクの失敗によるディスク領域の枯渇を防ぐために、レプリケーションスロットの状態と WAL ストレージを監視する必要があります。 | スキーマ変更やデータ移行後もトリガーが正しく機能することを確認するために、トリガーを管理する必要があります。 |
クイックスタート
このセクションでは、テーブルの自動コンパクションタスクをインストール、設定、有効化するまでの全プロセスを説明します。
ステップ 1:クラスターパラメーターの設定
PolarDB コンソールにログインします。クラスター ページで、対象のクラスターを見つけてその ID をクリックします。
左側のナビゲーションウィンドウで、 を選択します。
パラメーター ページで、次のパラメーターを変更します:
wal_level:logicalに設定します。これは論理デコーディングを使用するための前提条件であり、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に変更します。
パラメーター設定が有効になるまで、クラスターが再起動するのを待ちます。
ステップ 2:拡張機能のインストールと起動
表領域を再編成したい対象のデータベースで pg_squeeze を有効にします。
対象のデータベースに接続します。
次の SQL ステートメントを実行して拡張機能を作成し、スケジューラワーカーを起動します。このプロセスは、
squeeze.tablesの設定に基づいて定期的にコンパクションタスクをチェックし、開始します。-- 対象のデータベースに拡張機能を作成 CREATE EXTENSION pg_squeeze; -- バックグラウンドスケジューラプロセスを開始 -- この操作は、pg_squeeze を使用する各データベースで一度だけ実行する必要があります SELECT squeeze.start_worker();(オプション) 次の SQL ステートメントを実行して、バックグラウンドプロセスが正常に開始されたことを確認します。
application_nameがsqueeze schedulerのプロセスが表示されれば、プロセスは正常に開始されています。SELECT * FROM pg_stat_activity WHERE application_name LIKE 'squeeze%';
ステップ 3:処理対象テーブルの設定
pg_squeeze が管理するテーブルを指定し、それらのチェックおよびコンパクションポリシーを定義します。
テーブルに
レプリカ 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;
テーブルを
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 のコア設定ハブです。このテーブルを使用して、テーブルを登録し、その処理ポリシーを定義します。
パラメーター | 型 | 説明 | デフォルト | 推奨事項 |
|
| テーブルのスキーマ名。 | - | - |
|
| テーブルの名前。 | - | - |
|
| タスクチェックのスケジュール。 | - | ビジネスのオフピーク時間または低トラフィックのウィンドウに合わせて設定します。例えば、毎日午前 2:30 に実行する場合: |
|
|
| 50 | 書き込みが多い OLTP テーブルの場合、この値を低くする (例:30) ことを検討し、より頻繁に小さなバッチで領域を再利用します。 |
|
| 最小テーブルサイズ (MB)。これより小さいテーブルは処理されません。 | 8 | 小さなテーブルでの不要な操作を避けるために、デフォルト値を維持します。 |
|
| 最後の | '1 hour' | デフォルト値を維持します。この時間を超えると、 |
|
| 初期コンパクションが失敗した場合に許可される最大リトライ回数。 | 0 | DDL 変更やその他の理由でテーブルのコンパクションが頻繁に失敗する場合、この値を増やす (例:2) ことを検討し、タスクの成功率を向上させます。 |
|
| 既存のインデックスを指定します。コンパクション後、テーブル内のデータは、 |
| 範囲で頻繁にクエリされるテーブルの場合、プライマリキーまたはコアクエリインデックスをクラスタリングインデックスとして設定することを検討してください。これにより、クエリパフォーマンスが大幅に向上する可能性があります。 |
|
| コンパクション後にテーブルが移動するターゲット表領域を指定します。 |
| 表領域の移行シナリオで使用されます。 |
|
| インデックスの表領域マッピングを指定するために使用される 2 次元配列。 |
| インデックス表領域の移行に使用されます。 |
|
| コンパクション後に |
| これを |