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 以外の値に設定されている場合、サブスクライバーはパブリッシャーからのトランザクションストリーミングを要求します。これがどのように提供されるかは、グループ構成設定によっても異なります。詳細は bdr.default_streaming_modeを使用したノード構成 を参照してください。

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ライタのステータスは :ref:``bdr.writers`<bdr.writers>` を参照してください。

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

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 —完全に受信されたストリーミング トランザクションの数。