Eager Replication

コミット後の競合を防ぐには、 bdr.commit_scope パラメーターをglobal に設定します。 local のデフォルト設定はEager Replicationを無効にするため、 競合の監視 で説明されているように、 BDRはコミット後に変更を適用し、潜在的な競合を解決します。

このモードでは、 BDRは内部で2フェーズコミット(2PC)を使用して、ローカルコミットの前に競合を検出および解決します。これは、アプリケーションの通常のCOMMIT を暗黙的な2フェーズコミットに変換し、元のノードがコミットを続行する前に、すべてのピアノードでトランザクションを準備する必要があります。準備フェーズ中に少なくとも1つのノードがダウンしているか到達できない場合、コミットはbdr.global_commit_timeout の後にタイムアウトし、トランザクションが中止されます。 PostgreSQLの明示的な2PCに存在する一時テーブルの使用に制限はありません。

準備ができると、 Eager All-Node Replicationは Raft を使用してコミットの決定に到達します。障害が発生した場合、これにより、残りの大部分のノードが一致するコミットまたはアボートの決定に到達して、トランザクションを終了できます。これにより、トランザクションによってロックされたオブジェクトとリソースのブロックが解除され、クラスターが続行できます。

すべてのノードが動作可能なままである場合、オリジンはすべてのノードがコミットした後にのみクライアントにコミットを確認し、コミット後にすべてのノードでトランザクションがすぐに表示されるようにします。

要件

Eager All-Node Replicationは、準備されたトランザクションを内部で使用します。したがって、すべてのレプリカノードは、場合によってはローカルの2フェーズコミットとCAMOトランザクションに加えて、すべての着信トランザクションを処理できるように max_prepared_transactions を構成する必要があります。 (

Configuration: Max-prepared transactions を参照)。すべてのノードで同じに、 CAMOまたはEager

All-Node Replicationが使用されるクラスター全体の同時トランザクションの最大数をカバーするのに十分な高さで構成することをお勧めします。それ以外は、特別な構成は必要なく、すべてのEDB Postgres分散クラスターはEager All-Nodeトランザクションを実行できます。

使用法

Eager All-Node Replicationを有効にするには、次に示すように、クライアントはセッションレベルまたは個々のトランザクションでグローバルコミットスコープに切り替える必要があります。

BEGIN;

... other commands possible...

SET LOCAL bdr.commit_scope = global;

... other commands possible...

クライアントは、トランザクションの最後にCOMMIT を発行し続け、 BDRに2つのフェーズを管理させることができます。

COMMIT;

エラー処理

BDRがトランザクションを管理することを考えると、クライアントはCOMMIT の結果のみを確認する必要があります。 (これは、シングルノードのPostgresを含むいずれの場合にもお勧めします。)

起点ノードに障害が発生した場合、残りのノードは最終的に(少なくともbdr.global_commit_timeout の後)、グローバルに準備されたトランザクションをロールバックすることを決定します。 Raft は、一貫性のないコミットとロールバックの決定を防ぎます。ただし、これには接続されたノードの大部分が必要です。切断されたノードは、必要に応じてトランザクションを最終的にコミット(またはロールバック)して、決定してさらに進んだ可能性のあるノードの大部分と調整します。

CAMOを使用したEager All-Node Replication

Eager All-Node ReplicationはCAMOを超えて、それを意味します。 bdr.commit_scope がglobal に設定されている場合、bdr.enable_camo も有効にする必要はありません。また、 CAMOペアをbdr.add_camo_pair() で構成する必要もありません。

CAMOパートナーのロールで他のアクティブなBDRノードを使用して、トランザクションのステータスを照会できます。ただし、この非CAMO使用法をrequire_camo_partner = false の3番目の引数でbdr.logical_transaction_status 関数に示す必要があります。それ以外の場合、 CAMO構成がないと不平を言う場合があります(Eagerトランザクションには必要ありません)。

その関数の構成と呼び出しの違いを除き、クライアントは show-camo で説明されているプロトコルに従う必要があります。リファレンスクライアントの実装は、要求に応じて顧客に提供されます。

制限事項

Eager Replicationを使用するトランザクションはまだDDLを実行できません。明示的な2フェーズコミットもサポートしていません。これらは後のリリースで許可される可能性があります。 TRUNCATE コマンドは許可されています。

クラッシュした回復不能なBDRノードをフィジカルスタンバイに置き換えることは、現在、Eager All-Nodeトランザクションと組み合わせてサポートされていません。

BDRは現在、グローバルコミットスコープのみを提供しています。後のリリースでは、可用性を高めるために少ないノードでEager Replicationをサポートします。

Eager All-Node Replicationとsynchronous_replication_availability = 'async' を組み合わせることはできません。両方を構成しようとすると、エラーが発生します。

Eager All-Nodeトランザクションは、現在、Decoding Worker機能またはトランザクションストリーミングと組み合わせてサポートされていません。 Eagerを使用したインストールでは、 BDRノードグループでenable_wal_decoder およびstreaming_mode を無効にしておく必要があります。

同期レプリケーションは、Eagerとは異なるトランザクション確認のメカニズムを使用します。この2つは互換性がありません。一緒に使用しないでください。したがって、Eager All-Nodeトランザクションを使用するときは常に、synchronous_standby_names でBDRノードが構成されていないことを確認してください。フィジカルスタンバイとして動作する非BDRノードへの同期レプリケーションを使用できます。

一般的なEager Replicationの効果

コミットのレイテンシーの増加

同期ステップを追加することは、ノード間の追加の通信を意味し、コミット時に追加のレイテンシーが発生します。 Eager All-Node Replicationは、約2つのネットワークラウンドトリップを追加します(最悪の場合、最も遠いピアノードへ)。ロジカルスタンバイノードと、まだ参加またはキャッチアップ中のノードは含まれませんが、最終的に変更を受け取ります。

ピアノードは、トランザクションのローカル準備を確認する前に、ローカルに適用する必要があります。これにより、トランザクションのサイズによっては、コミットのレイテンシーがさらに増加します。これはsynchronous_commit 設定とは無関係で、bdr.commit_scope がglobal に設定されている場合は常に適用されます。

アボート率の増加

注釈

Eager Replicationのパフォーマンスは現在、予想外に遅いことが知られています(約10 TPSのみ)。これは次のリリースで改善される予定です。

シングルノードPostgres、またはデフォルトの非同期レプリケーションモードのBDRを使用しても、 COMMIT 時のエラーはまれです。追加の同期ステップによりエラーのソースが追加されるため、アプリケーションはこのようなエラーを適切に処理するように準備する必要があります(通常は再試行ループを適用します)。

アボートの率は、ワークロードのみに依存します。多くの行を変更する大規模なトランザクションは、他の同時実行トランザクションと競合する可能性がはるかに高くなります。