Eager Replication

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

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

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

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

要件

Eager All-Node Replicationは準備されたトランザクションを内部で使用します。したがって、すべてのレプリカノードは、すべての着信トランザクションをハンドルできるように十分な高さに max_prepared_transactions を構成する必要があります(おそらくローカル二相コミットおよびCAMOトランザクションに加えて。

Configuration: Max Prepared Transactions

を参照)。すべてのノードで同じに、CAMOまたはEager全ノードレプリケーションが使用されるクラスター全体の同時トランザクションの最大数をカバーするのに十分な高さに構成することをお勧めします。それ以外は、特別な構成は必要なく、すべてのBDRクラスターで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がトランザクションを管理することを考えると、クライアントはニーズの結果を確認するだけです(シングルノードの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トランザクションには必要ありません)。

そのファンクションの構成と呼び出しの違いを除き、クライアントは

CAMO/フェイルオーバーオプションを使用したpgbench で説明されているプロトコルに従うニーズがあります。 reference client implementations を参照してください。

制限事項

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

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

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

Eager All Nodeレプリケーションをsynchronous_replication_availability = 'async' と組み合わせることはできません。両方を構成しようとするとエラーが発生します。

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

同期レプリケーションは、Eagerとは異なるトランザクション確認のメカニズムを使用します。 2つは互換性がないため、一緒に使用しないでください。したがって、Eager All Nodeトランザクションを使用するときは常に、synchronous_standby_names でBDRノードが構成されていないmakeを確認してください。物理的スタンバイとして機能する非BDRノードへの同期レプリケーションを使用することは十分に可能です。

一般的な熱心な複製の効果

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

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

同等ながトランザクションのローカル準備を確認できる前に、ローカルにも適用するニーズがありノード。これにより、トランザクションのサイズによっては、コミットのレイテンシがさらに長くなります。これはsynchronous_commit 設定とは無関係であり、bdr.commit_scope がglobal に設定されている場合は常に適用されることに注意してください。

アボート率の増加

注釈

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

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

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