Choosing commit scopes#

DBA コミットスコープへの移行 し、グループまたはサブグループレベルでデフォルトを設定します。セッションごとまたはトランザクションごとにスコープを設定して、より強いまたは弱い耐久性保証が必要な操作のグループのデフォルトをオーバーライドします。適切なスコープを選択することは、それぞれのレイテンシーのコストと、レプリケーションが完了する前にノードに障害が発生した場合にどうなるかを理解することを意味します。

DBAが各ノードグループに対して構成したデフォルトのコミットスコープを表示するには

SELECT node_group_name, default_commit_scope
FROM bdr.node_group_summary;

適切なスコープの選択#

各スコープは、書き込みコミット後に何が起こるかについて異なる約束をします。正しい選択は、レプリケーションが完了する前にノードに障害が発生した場合にアプリケーションが何を許容できるかによって異なります。

ローカルプロテクト#

高スループットのイベントストリーム、分析の取り込み、または耐久性よりも書き込みレイテンシーが重要なワークロードなど、最近の書き込みの損失が許容されるデータにはローカル保護を使用します。トランザクションはローカルでコミットし、他のノードに非同期でレプリケートするため、レプリケーションが完了する前にノードに障害が発生すると、書き込みが失われることを意味します。レプリケーションが追いつくまでに、別のノードでの読み取りは、わずかに古いデータを返す場合があります。

マジョリティプロテクト#

アカウントの更新、顧客レコード、ほとんどのトランザクションデータなど、失われることはできないが、追加の遅延が許容される場合の書き込みにはマジョリティ保護を使用します。コミットは、オリジングループ内のノードの大部分が返す前に確認を待機するため、アプリケーションが続行する前にマルチプルのノードにわたって書き込みが持続します。コストは、書き込みごとの追加往復レイテンシーであり、マルチリージョンクラスターの場合、通常は数十〜数百ミリ秒です。

アダプティブプロテクト#

1つのデータノードが到達不能になった場合にストリクトマジョリティ保護が失敗する2ノードプラスWitnessグループには、アダプティブ保護を使用します。アダプティブ保護は、ノードの大部分が利用可能な場合、マジョリティ保護のように動作しますが、一時的に耐久性が低下するというコストで、一時的なネットワークの問題中に構成可能なタイムアウトの後、非同期レプリケーションに正常に低下します。

CAMO#

支払い、資金移動、および同じトランザクションを2回適用すると不正確な結果が発生するオペレーションにCAMOを使用します。コミットは専用のパートナーノードを待機し、トランザクションが1回だけ適用されることを保証します。コミット中に接続がドロップした場合でも、アプリケーションはトランザクションの運命を照会し、再試行するかどうかを決定できます。 CAMO、スコープの設定を超えてアプリケーションコードの変更が必要です。再試行パターンについては、 CAMO再試行ワークフロー を参照してください。

CAMOには、 CAMOグループ内の正確に2つのデータノードが必要で、マジョリティ保護よりも高いコミットレイテンシが追加されます。これは、その遅延が受け入れられない高スループットのワークロードには適切ではありません。

クォーラムコミット#

分散一貫性が必要で、事後に競合を解決できない決済、コアバンキング、および台帳システムにクォーラムコミットを使用します。耐久性を確認するマジョリティ保護とは異なり、クォーラムコミットは、ノードがローカルにコミットする前に、すべての参加ノードにわたってコミット決定を調整します。 2つのトランザクションが競合する場合、一方はコミットフェーズ中に、いずれかがコミットする前にアボートされます。

クォーラムコミットは熱心な競合解決を使用するため、アプリケーションは他のスコープよりもコミット時にシリアル化エラーに遭遇します。再試行ループの例を含むセットアップ、構成、およびアプリケーションパターンについては、 Using Quorum Commit を参照してください。

スコープの設定#

ほとんどの操作でグループのデフォルトを使用し、それが必要な書き込みの場合にのみより強力なスコープにオーバーライドします。

接続上のすべての操作が同じ耐久性要件を共有する場合、支払い処理のみに使用される専用接続など、セッションごとにスコープを設定します。単一の接続が混合ワークロードを処理し、特定の操作のみがより強力な保証を必要とする場合、トランザクションごとに設定します。

  • セッションごと セッションレベルでbdr.commit_scope を設定して、その接続内のすべてのトランザクションにスコープを適用します。

SET bdr.commit_scope = majority protect;

セッション内の後続のすべてのトランザクションは、変更するかセッションが終了するまで、このスコープを使用します。

  • トランザクションごと トランザクション内でSET LOCAL を使用して、そのトランザクションのみのスコープをオーバーライドします。セッションレベルの設定は、トランザクションが終了すると復元されます。

BEGIN;
SET LOCAL bdr.commit_scope = majority protect;
-- critical write operations
COMMIT;

重要

クォーラムコミットは、それを使用するトランザクションが、使用しないトランザクションと同じテーブルで同時に実行される場合、一貫性を保証しません。ノードグループのデフォルトがクォーラムコミットスコープの場合、同じテーブルにタッチするトランザクションの弱いスコープにオーバーライドすることは避けてください。

現在のセッションでアクティブなコミットスコープを確認するには

SHOW bdr.commit_scope;

その他の考慮事項#

大量操作#

高スループットの大量操作には同期スコープの使用を避けてください。トランザクションごとのラウンドトリップレイテンシーの追加は、大規模なバッチ全体で増加し、大量のロードが大幅に遅くなる場合があります。大量操作をスコープごとに分割する 重要なレコードには強力なスコープを使用し、残りの部分にはデフォルトを使用します。

タイムアウトしたコミット#

コミットスコープがリモート確認を必要とし、リモートの場所に到達できない場合、トランザクションは失敗します。再試行ロジックは一時的なネットワーク障害を処理しますが、タイムアウトしたコミットには特別な注意が必要です。コミットがタイムアウトした場合、結果は不明です。トランザクションは、タイムアウト前に一部のノードでコミットされた可能性があります。重複したアプリケーションが受け入れられない操作には、 CAMO を使用します。 CAMO再試行ワークフロー を参照してください。

自分の書き込みを読む#

アプリケーションが1つの接続に書き込み、すぐに別の接続を読み取る場合、読み取りはレプリケーションをまだ受け取っていないノードに到達する可能性があります。後続の読み取りが以前の書き込みを反映することを保証するには、書き込みトランザクションで同期コミットスコープを使用します。書き込みが必要なノードにレプリケートされるまでコミットは返されないため、これらのノードでの後続の読み取りは書き込みを参照します。

BEGIN;
SET LOCAL bdr.commit_scope = majority protect;

- - Insert a new transaction for a known account
INSERT INTO transactions (transaction_id, account_id, direction, amount, balance_after, description, channel, initiated_at)
VALUES (
    uuidv7(),
    <account_id>,
    D,
    250.00,
    <balance_after>,
    Online purchase,
    ONLINE,
    NOW()
)
RETURNING account_id, transaction_id, balance_after;

COMMIT;

- - This read now reflects the insert on any node in the majority
SELECT balance_after
FROM transactions
WHERE transaction_id = <returned-transaction-id>;