Conflict detection#

PGDは、競合検出のための次のメカニズムを提供します。

オリジンの競合検出#

オリジン競合検出は、トランザクションの発生元のノードに記録されたコミットタイムスタンプを使用および依存します。これには、クロックが正しく動作するか、2つのノード間の最速のメッセージの許容範囲内に同期している必要があります。これが当てはまらない場合、競合解決はより前にあるノードを優先する傾向があります。パラメーターbdr.maximum_clock_skew およびbdr.maximum_clock_skew_action を使用して、ノード間のクロックスキューを管理できます。

注釈

ローカルノードのクロックがリモートノードのコミットタイムスタンプより遅れている場合、グループコミットスコープを使用するトランザクションではコミットレイテンシーが増加します。ローカルノードは、ローカルのタイムスタンプがリモートコミットタイムスタンプより古くなるまで待機する必要があるため、 bdr.maximum_clock_skew または`bdr.maximum_clock_skew_action` の設定に関係なく発生します。 最適なパフォーマンスを保証し、遅延を最小限に抑えるには、システムクロックを厳密に同期する必要があります。

競合は、レプリケーション元が変更されたかどうかに基づいて最初に検出されるため、競合と判明しない可能性のある状況で競合トリガーが呼び出されます。したがって、このメカニズムは正確ではありません、偽陽性の競合を生成する可能性があります。

元の情報は、行がフリーズされた時点まででのみ利用できます。凍結された後に行に到着する更新は競合を発生させないため、すべての場合に適用されます。これはbdr_init_physical によって新しいノードを追加する場合の通常のケースであるため、競合が発生すると、その場合に多くの偽陽性の結果が発生します。

オフラインだったノードが再接続してデータ変更の送信を開始すると、新しく到着した更新が更新する凍結行よりも古い場合、発散エラーが発生する可能性があります。挿入と削除は、この状況の影響を受けません。

Node restart and down node recovery で説明しているように、長時間の停止のためにノードをダウンしたままにしないことをお勧めします。

EDB Postgres Extended ServerおよびEDB Postgres Advanced Serverでは、ノードがダウンしている間、PGDは行のフリーズを抑制します。このメカニズムはこの状況を適切に処理するため、パラメーター設定を変更する必要はありません。

Postgresの他のバリアントでは、この状況をある程度注意して管理する必要がある場合があります。

フリーズは、通常、バキュームされる行が現在のxidからvacuum_freeze_min_age xidより古い場合に発生します。これは、これらのパラメーターに適切に高い値を構成する必要があることを意味します。

  • vacuum_freeze_min_age

  • vacuum_freeze_table_age

  • autovacuum_freeze_max_age

トランザクションレートに基づいて値を選択し、データベースノードから競合データを削除する前にダウンタイムの猶予期間を与えます。たとえば、vacuum_freeze_min_age が5億に設定されている場合、1000TPSを実行するノードは、競合データが削除されるまで5.5日強の間ダウンする可能性があります。 CommitTSデータ構造は、その設定で5 GBのディスク上の領域を必要とするため、トランザクションレートの低いシステムはより低い設定からメリットを得ることができます。

最初に、推奨される設定は次のとおりです。

#  1 billion = 10GB

autovacuum_freeze_max_age = 1000000000

vacuum_freeze_min_age = 500000000

#  90% of autovacuum_freeze_max_age

vacuum_freeze_table_age = 900000000

次のことに注意してください。

  • autovacuum_freeze_max_age はノード起動時にのみ設定できます。

  • vacuum_freeze_min_age を設定できるため、低い値を使用すると行が早期にフリーズし、競合が無視される場合があります。個々のテーブルにautovacuum_freeze_min_age およびtoast.autovacuum_freeze_min_age を設定することもできます。

  • CLUSTER またはVACUUM FREEZE コマンドを実行しても、行が早期にフリーズされ、競合が無視される場合があります。

行バージョンの競合検出#

PGDは、行バージョン管理を使用し、ノードのシステムクロックとは無関係に競合検出を行うオプションを提供します。

行バージョンの競合検出には、3つのことを有効にする必要があります。これらの手順のいずれかが正しく実行されない場合、 オリジンの競合検出 が使用されます。

  • 行バージョンの競合検出を使用するすべてのテーブルでREPLICA IDENTITY FULL を有効にします。

  • bdr.alter_table_conflict_detection を使用して、テーブルの行バージョンの追跡を有効にします。このファンクションは、指定した名前の列と、新しい列値を管理するUPDATE トリガーを追加します。列はINTEGER タイプとして作成されます。

カウンタはUPDATE でのみインクリメントされますが、この技術により、 UPDATE とDELETE の両方の競合検出が可能になります。

このアプローチはランポートタイムスタンプに似ており、競合検出のABA問題を完全に防止します。

注釈

行レベルの競合解決は、行バージョン管理を使用しても 欠落列の競合の解決 構成に基づいて処理されます。行バージョンの生成方法は、競合を検出する場合にのみ役立ちます。行のどのバージョンが新しいかに関する信頼できる情報として依存しないでください。

特定のテーブルに使用されている現在の競合検出ストラテジーを判断するには、ビュー bdr.tables の列conflict_detection を参照してください。

現在の競合検出ストラテジーを変更するには、 bdr.alter_table_conflict_detection を使用します。