Transaction streaming

ロジカルレプリケーションでは、トランザクションはパブリッシャーで同時にデコードされますが、トランザクションがコミットされるまでサブスクライバーには送信されません。変更が logical_decoding_work_mem (PostgreSQL 13以降)を超える場合、それらはディスクにスピルされます。これは、特にラージトランザクションでは、サブスクライバーに到達するまでに遅延が発生し、パブリッシャーで追加のI / Oが必要になることを意味します。

PostgreSQL 14以降、トランザクションはオプションでデコードして、パブリッシャーでコミットされる前にサブスクライバーに送信できます。サブスクライバーは、受信した変更をステージングファイル(またはファイルのセット)に保存し、トランザクションのコミット時に適用します(またはトランザクションが中断した場合は破棄します)。これにより、トランザクションがコミットされるとすぐにサブスクライバーにトランザクションを適用できます。

BDRの機能強化

上記のように、PostgreSQLのビルトイントランザクションストリーミングには次の制限があります。

  • パブリッシャーで変更をディスクに書き込む必要はなくなりましたが、変更は各サブスクライバーでディスクに書き込む必要があります

  • トランザクションが打ち切られた場合、作業(各サブスクライバーが受け取った変更と関連するストレージI / O)は無駄になります

ただし、バージョン3.7から、 BDRはパラレル適用をサポートし、各サブスクライバでマルチプルのライタプロセスを有効にします。これを活用して、次の機能強化を提供します。

  • デコードされたトランザクションは、サブスクライバーのライタに直接ストリーミングできます

  • デコードされたトランザクションは、サブスクライバーのディスク上に保存する必要はありません

  • サブスクライバーでトランザクションの適用を開始する前に、トランザクションがコミットのを待つ必要はありません

警告

  • 並列適用を有効にする必要があります

  • ワークロードが多くの小さくて競合するトランザクションで構成されている場合、これはライター間で頻繁にデッドロックを引き起こす可能性があります

注釈

ライタへの直接ストリーミングはまだ実験的な機能であり、使用には注意が必要です。具体的には、ストリーミングのコミットタイムスタンプを利用できない場合があるため(トランザクションがオリジンでまだコミットされていない可能性があるため)、競合解決ではうまく機能しない場合があります。

構成

トランザクションストリーミングは次の 2 つの場所で構成されます。

bdr.default_streaming_modeを使用したノード構成

許可される値は次のとおりです。

  • off

  • writer

  • file

  • auto

デフォルト値はauto です。

この設定を有効にするには、サブスクリプションごとにpglogicalレシーバプロセスをリスタートする必要があることに注意してください。これは、サーバーリスタートで実現できます。

bdr.default_streaming_mode がoff 以外の値に設定されている場合、サブスクライバーはパブリッシャーにトランザクションストリーミングを要求します。これがどのように提供されるかは、グループ構成設定によっても異なります。詳細については、以下のXXXを参照してください。

bdr.alter_node_group_config()を使用したグループ構成

ファンクション bdr.alter_node_group_config()を使用したグループ構成 のパラメータstreaming_mode を使用して、グループトランザクションストリーミング構成を設定できます。

許可される値は次のとおりです。

  • off

  • writer

  • file

  • auto

  • default

デフォルト値はdefault です。

現在の設定の値は、ビュー :ref:bdr.node_group`<`bdr.node_group`>`  の列 ``node_group_streaming_mode に含まれています。返される値は単一のchar型で、取り得る値はD (default )、W (writer )、F (file )、A (auto )およびO (off )です。

構成設定の効果

トランザクションストリーミングは、GUC bdr.default_streaming_mode によってサブスクライバーレベルで制御されます。 off (トランザクションストリーミングを無効にする)に設定されていない限り、サブスクライバーはトランザクションストリーミングを要求します。

パブリッシャーがトランザクションストリーミングを提供できる場合、トランザクションサイズがlogical_decoding_work_mem で設定されたしきい値を超えるたびにトランザクションをストリームします。通常、パブリッシャーは、トランザクションをファイルにストリーミングするかライタにストリーミングするかを制御できません。一部の状況(COPYなど)を除き、サブヒントにトランザクションをライタにストリームするように指示する場合があります(可能な場合)。

サブスクライバーは、パブリッシャーから受け取ったトランザクションをライタまたはファイルにストリームできます。この決定は、いくつかの要因に基づいています。

  • 並列適用がオフの場合(num_writers = 1)、ファイルにストリーミングされます(ライタ0は常に非ストリーミングトランザクション用に予約ています)

  • 並列適用がオンになっているが、すべてのライターがストリーミングされたトランザクションのハンドリングで既にビジー状態である場合、新しいトランザクションはファイルにストリーミングされます。 [bdr.writers](モニタリング#monitoring-bdr-writers) を参照して、 BDRライタのステータスを確認してください。

ライタへのストリーミングが可能な場合(つまり、フリーのライタが利用できる場合)、トランザクションをライタにストリームするかファイルにストリーミングするかは、次の表のようにグループとノードの設定の組み合わせに基づいています。

Group

Node

Streamed to

off

(any)

(none)

(any)

off

(none)

writer

file

file

file

writer

file

default

writer

writer

default

file

file

default

auto

writer

auto

(any)

writer

グループ構成がauto に設定されている場合、またはグループ構成がdefault であり、ノード構成がauto である場合、パブリッシャーがこれを行う必要があると示唆した場合にのみ、トランザクションがライタにストリーミングされることに注意してください。

現在、パブリッシャーは、次のトランザクションタイプのライタにストリームするようにサブヒントにライタしフリー。

  • COPY

  • CREATE INDEX CONCURRENTLY

モニタリング

トランザクションストリーミングの使用は、サブスクライバーノードの :ref:``bdr.stat_subscription`<bdr.stat_subscription>` ファンクションを介して監視できます。

  • nstream_writer -ライタにストリーミングされたトランザクションの数

  • nstream_file -ファイルにストリーミングされたトランザクションの数

  • nstream_commit -コミットされたストリーミングトランザクションの数

  • nstream_abort -中断されたストリーミングトランザクションの数

  • nstream_start -開始されたストリーミングトランザクションの数

  • nstream_stop -完全に受信されたストリーミングトランザクションの数