Using pg_squeeze#

通常処理のためのテーブルの登録#

最初に、テーブルに主キーまたは一意性制約のいずれかが存在することを確認します。これは、 pg_squeeze が作業を行っているときに他のトランザクションから発生した変更を処理するために必要です。

pg_squeeze 拡張機能にテーブルを認識させるには、squeeze.tables テーブルにレコードを挿入する必要があります。追加後、テーブル統計は定期的にチェックされます。テーブルがスクイーズに必要な基準を満たしている場合、タスクがキューに追加されます。タスクは作成された順にシークエンシャルに処理されます。

次に、簡単な登録の例を示します。

INSERT INTO squeeze.tables (tabschema, tabname, schedule)
VALUES (public, foo, ({30}, {22}, NULL, NULL, {3, 5}));

オプションで追加の列を指定できます。例

INSERT INTO squeeze.tables (
    tabschema,
    tabname,
    schedule,
    free_space_extra,
    vacuum_max_age,
    max_retry
)
VALUES (
    public,
    bar,
    ({30}, {22}, NULL, NULL, {3, 5}),
    30,
    2 hours,
    2
);

次のリストでは、テーブルのメタデータを説明します。

  • tabschema —スキーマ名。

  • tabname —テーブル名。

  • schedule —テーブルをチェックし、場合によってはスクイーズする場合を指定します。スケジュールは、次の複合データ型の値で記述されます。これは、crontabエントリに似ています。

CREATE TYPE schedule AS (
    minutes       minute[],
    hours         hour[],
    days_of_month dom[],
    months        month[],
    days_of_week  dow[]
);

このデータタイプでは、 minutes 0-59およびhours 0-23は、1日以内にチェックが発生した時間を決定しますが、 days_of_month 1-31、months 1-12、およびdays_of_week 0-7、 0と7は両方とも日曜日を表します)によって、小切手の日が決まります。

minutes 、hours 、およびmonths がすべて現在のタイムスタンプと一致する場合に、チェックが実行されます。 NULL は、それぞれ分、時、月を意味します。チェックが行われるには、days_of_month またはdays_of_week のいずれかが現在のタイムスタンプと一致するか、両方がNULL である必要があります。

たとえば、サンプル登録のエントリは、毎週水曜日と金曜日の22:30にテーブルpublic.bar をチェックするように指定しています。

  • free_space_extra —テーブルの処理をトリガーするために必要な追加空き領域の最小割合。 extra 形容詞は、 fillfactor から派生する空き領域はテーブルを圧迫する理由ではないという事実を指します。

たとえば、fillfactor が60に等しい場合、通常のオペレーション中に各ページの少なくとも40パーセントが空きままになります。空き領域の70パーセントでpg_squeeze がテーブルに関心を持つようにしたい場合は、free_space_extra を30つまり、解放するために必要な70パーセントからfillfactor のための40パーセントを差し引いたものを設定します。

free_space_extra のデフォルト値は50です。

  • min_size —処理の対象となるためにテーブルが占有する必要があるメガバイト単位の最小ディスク領域。デフォルト値は8です。

  • vacuum_max_age —最後のVACUUM の完了から空き領域マップFSMが新しいと見なされるまでの最大時間。この間隔が経過すると、デッドタプルの部分が重要になる可能性があります。この場合、FSMをチェックするだけでなく、pg_squeeze の潜在的な効果を評価するためにより多くの労力を費やす必要があります。デフォルト値は1時間です。

  • max_retry —対応するタスクの最初の処理が失敗した場合に、テーブルをスクイーズしようとする追加の試行の最大数。処理を再試行する一般的な理由は、テーブルが圧迫されているときにテーブル定義が変更されたことです。再試行回数に達すると、テーブルの処理が完了したとみなされます。次のタスクは、次のスケジュールされた時刻に作成されます。 max_retry のデフォルト値は0ですつまり、再試行しません。

注釈

squeeze.table は、変更する唯一のテーブルです。他に変更したい場合は、自分が何をしているのかを理解してください。

テーブルのアドホック処理#

登録せずに、対応するレコードをsqueeze.tables に挿入せず、実際の肥大化を事前に確認せずに、テーブルを手動でスクイーズすることが可能です。

ファンクションシグネチャ

squeeze.squeeze_table(
    tabschema name,
    tabname name,
    clustering_index name,
    rel_tablespace name,
    ind_tablespaces name[]
)

次のリストでは、アドホック処理のテーブルメタデータを説明します。

  • clustering_index —処理されたテーブルのインデックス。処理が完了すると、テーブルのタプルがこのインデックスのキーによって物理的にソートされます。

  • rel_tablespace —テーブルの移動先の既存の表領域。 NULL は、テーブルを現在の場所に残すことを意味します。

  • ind_tablespaces —各行がインデックスのテーブルスペースマッピングを指定する2次元配列。最初と2番目の列は、それぞれインデックス名とテーブルスペース名を表します。マッピングが指定されていないすべてのインデックスは、元の表領域に残ります。 .. note::

    テーブルに表領域が指定されているが、インデックスは指定されていない場合、テーブルはその表領域に移動されますが、インデックスは元の表領域に残ります。言い換えれば、テーブルの表領域はインデックスのデフォルトではありません。

サンプル実行#

SELECT squeeze.squeeze_table(public, pgbench_accounts);

テーブル処理の有効化または無効化#

肥大化したテーブルの処理を有効にするには、スーパーユーザーとして次のステートメントを実行します。

SELECT squeeze.start_worker();

ファンクションは、バックグラウンドワーカーscheduler worker を起動します。特定のデータベースにタスクが存在するときは常に、別のワーカーsqueeze worker が起動されます。

スケジューラーワーカーが現在のデータベースで既に実行されている場合、ファンクションはエラーを報告せず、新しいワーカーはすぐに終了します。

ワーカーが現在のデータベースで実行されている場合、次のステートメントを使用してワーカーを停止できます。

SELECT squeeze.stop_worker();

注釈

このドキュメントで記載されている機能のみがユーザーインターフェイスの一部とみなされます。他のファンクションを呼び出したい場合は、自分が何をしているのかを理解してください。

PostgreSQLクラスター全体の起動中にバックグラウンドワーカーを起動したい場合は、次のようなエントリをpostgresql.conf ファイルに追加します。

squeeze.worker_autostart = my_database your_database
squeeze.worker_role = postgres

次回クラスターを起動したときに、2つ以上のワーカーつまり1つのスケジューラーワーカーと1つ以上のスクイーズワーカーがmy_database で起動され、your_database でも同じです。このアプローチを採用した場合、次のいずれかの場合、ワーカーは作業を実行せずに開始または停止しません。

  • pg_squeeze 拡張機能はデータベースに存在しません。

  • squeeze.worker_role パラメーターは、スーパーユーザー権限を持たないロールを指定しています。

実際には2つのワーカーがありますが、ここで説明するファンクションと構成変数は、ワードworker の単数形を使用しています。これは、タスクのスケジュールと実行の両方を保証していたpg_squeeze の以前のバージョンにはworker が1つだけ存在していたためです。したがって、この実装の変更は、アップグレード中にすべてのユーザーに構成ファイルの調整を強制するものではありません。

他のバックエンドへの影響の制御#

スクイーズされるテーブルは、ほとんどの場合、他のトランザクションによる読み取りおよび書き込み操作の両方に利用できますが、処理を終了するには排他ロックが必要です。 pg_squeeze がテーブルへのアクセスをブロックする場合がある場合は、 squeeze.max_xlock_time GUCパラメーターの設定を検討してください。例

SET squeeze.max_xlock_time TO 100;

この例では、0.1秒100ミリ秒を超えて排他ロックを保持しないように指定します。最終ステージにもっと時間が必要な場合、 pg_squeeze は排他ロックを解放し、間の他のトランザクションによってコミットされた変更を処理し、最終ステージを再試行します。ロック期間を数回超過すると、エラーが報告されます。その場合は、設定を増やすか、書き込みアクティビティが低い別の時間に問題のあるテーブルの処理をスケジュールします。

データベースごとに複数のワーカーを実行する#

単一のスクイーズワーカーが負荷に対応しないと考えられる場合は、 squeeze.workers_per_database 構成変数を1より大きい値に設定することを検討します。これにより、 pg_squeeze 拡張機能はマルチプルのテーブルを同時に処理できます。スクイーズワーカーごとに1つのテーブル。

ただし、この設定は、 pg_squeeze 拡張機能をアクティブに使用するすべてのデータベースに影響を与えることに注意してください。クラスター内のすべてのスクイーズワーカースケジューラーワーカーを含むの合計数は、コア内構成変数max_worker_processes を超えることはできません。

モニタリング#

squeeze.log テーブルには、正常にスクイーズされたテーブルごとに1つのエントリが含まれています。

列tabschema およびtabname は、処理されたテーブルを識別します。列started およびfinished は、処理が開始および終了した時期をレポートします。 ins_initial は、初期ロードステージ中に新しいテーブルストレージに挿入されたタプルの数、つまり、処理が開始される前にテーブルに存在していたタプルの数です。一方、ins 、upd 、およびdel は、テーブル処理中にアプリケーションによって挿入、更新、および削除されたタプルの数です。 (これらの同時データの変更も、スクイーズされたテーブルに組み込む必要があります。そうしないと、失われます。)

squeeze.errors テーブルには、スクイーズ中に発生したエラーが含まれています。よくある問題は、処理が進行中のテーブルの定義を変更する人がいるということです。つまり、列を追加または削除します。

squeeze.get_active_workers() ファンクションは、現在のデータベースでテーブルを処理しているスクイーズワーカーのテーブルを結果ます。

pid 列には、ワーカープロセスのシステムPIDが含まれています。他の列は、squeeze.log テーブルの対応する列と同じ意味を持ちます。 squeeze.log テーブルは、完了したスクイーズ操作に関する情報のみを表示しますが、 squeeze.get_active_workers() ファンクションを使用すると、処理中に進行状況を確認できます。

テーブルの登録解除#

特定のテーブルが定期的なスクイズの対象でなくなった場合、squeeze.tables テーブルから対応する行を削除します。

バックグラウンドワーカーは存在しないテーブルの登録を定期的に解除しますが、ドロップするテーブルの登録を解除することをお勧めします。

コンカレンシー#

pg_squeeze 拡張機能は、他のトランザクションが処理の特定の段階でテーブルを変更するのを妨げません。スクイーズが完了する前に、破壊的なコマンドつまり ALTER TABLE 、VACUUM FULL 、CLUSTER 、またはTRUNCATE がコミットできた場合、 squeeze_table() ファンクションは中止され、テーブルに加えられたすべての変更はロールバックされます。 squeeze.tables テーブルのmax_retry 列は、スクイズワーカーが再試行する回数を決定します。スケジュールを変更すると、この種の中断を回避できる場合があります。

pg_repack と同様に、pg_squeeze も行の可視性を変更するため、MVCCの Caveats の最初の段落で説明されているMVCC非安全な動作が許可されます。

ディスク領域の要件#

フルテーブルスクイーズを実行するには、ターゲットテーブルとそのインデックスの2倍の空きディスク領域が必要です。たとえば、圧縮するテーブルとインデックスの合計サイズが1GBの場合、追加で2GBのディスク領域が必要です。