CDC Failover support#

背景#

PGDの以前のバージョンでは、データベース内のデータに発生した論理変更のフィードを提供できるノードに論理レプリケーションスロットを作成できました。これらの論理レプリケーションスロットはノードに対してローカルであり、レプリケートされていません。特定のノードで変更をレプリケートするだけでなく、この動作は、クラスター内のノードフェールオーバーが発生した場合に課題を提示しました。そのシナリオでは、障害が発生したノードの論理レプリケーションのコンシューマには、別のノードに消費を継続するスロットのレプリカがありません。

この問題へのソリューションは、サブスクライバ専用ノードを中間として使用して設計できますが、論理レプリケーションのコストが大幅に増加します。

CDCフェイルオーバーのサポート#

このニーズに対応するために、PGDはCDCフェールオーバーサポートを導入しました。これは、クラスター全体で自動論理スロットレプリケーションをアクティブにするオプションで有効な機能です。これにより、論理スロットのレプリケーションのコンシューマは、障害が発生したときに任意のノードから変更データを受信できます。

CDCフェールオーバーの仕組み#

CDCフェールオーバーサポートが有効になっているノードで論理スロットが作成されると、スロットはクラスター全体でレプリケートされます。これは、クラスター内の任意のノードでスロットを使用できることを意味します。ノードに障害が発生すると、クラスター内の別のノードからスロットが消費される可能性があります。これにより、論理レプリケーションストリームを中断せずに継続できます。

ただし、スロットのコンシューマがクラスター内の別のノードに接続する場合、コンシューマが以前に持っていた接続はPGDによって閉じられます。この動作は、スロットがマルチプルのノードから同時に消費されないようにするためです。バックグラウンドで、PGDはRaftコンセンサスプロトコルを使用して、スロットが一度に1つのノードのみから消費されるようにしています。これは、一度に1つのスロットのみが消費されるという保証が、スプリットブレインシナリオでは成立しないことを意味します。

現在、CDCフェールオーバーのサポートは、トップグループオプションによって制御されるグローバルオプションです。 failover_slot_scope トップグループオプションは現在、論理スロットのレプリケーションを無効にするlocal またはglobal に設定できます。デフォルト。 global 設定は、 PGDデータベースで作成されたすべての非一時論理スロットのレプリケーションを有効にします。

一時論理スロットは、有効期間がそれらを作成したセッションにスコープされ、そのセッションが終了すると消失するため、レプリケートされません。

少なくとも1回の配信保証#

CDCフェールオーバーサポートは、コンシューマーがすべての変更を少なくとも1回受信できるようにするための手順を実行します。これは、配信が確認されるまでスロットを抑制することにより行われ、その時点でスロットは非同期方法ですべてのノードで進められます。スロットが消費されていたノードに障害が発生した場合、スロットは、コンシューマがクラスター内のノードに接続するまで保持されます。これにより、スロットが進行できます。

1回限りの配信#

現在、正確に1回だけの配信を保証する方法はなく、使用するアプリケーションが、以前に完了したトランザクションの破棄を管理することを期待しています。

CDCフェールオーバーサポートの有効化#

CDCフェールオーバーのサポートを有効にするには、 SQLコマンドを実行し、次のパラメーターを使用して bdr.alter_node_group_option ファンクションを呼び出します。

select bdr.alter_node_group_option(<top-level group name>,
     failover_slot_scope,
     global);

<top-level group name> は、クラスターのトップレベルグループの名前に置き換えます。名前がわからない場合は、 bdr.node_group のnode_group_parent_idが0に等しいグループです。

名前がわからない場合は、 bdr.node_group で0に等しいnode_group_parent_idを持つグループです。次のものも使用できます。

SELECT bdr.alter_node_group_option(
     node_group_name,
     failover_slot_scope,
     global)
    from bdr.node_group
    where node_group_parent_id=0;

このコマンドにより、正しいトップレベルグループのオプションを設定できます。

CDCフェールオーバーが有効になったら、新しいグローバルにレプリケートされたスロットを作成するには、以下を使用できます。

SELECT pg_create_logical_replication_slot(myslot,
                                          test_decoding);

オプションがglobal に設定される前に作成された論理レプリケーションスロットはレプリケートされません。新しいスロットのみが複製されます。

フェールオーバースロットは、レプリケーション接続でCREATE_REPLICATION_SLOT コマンドを使用して作成することもできます。

フェイルオーバースロットのステータスは、 bdr.failover_replication_slots テーブルで追跡されます。

Postgres 17+でのCDCフェールオーバーのサポート#

Postgres 17以降では、フェールオーバーのサポートが追加され、スタンバイを再開できるようになりました。このためには、 failover という名前のpg_create_logical_replication_slot のオプションを使用します。この新しい設定では、 failover_slot_scope の設定に関係なく、 failover をtrue に設定する必要があります。

SELECT pg_create_logical_replication_slot(myslot,
                                          test_decoding,
                                          failover=>true);

一貫した初期スナップショットの取得#

論理レプリケーションスロットが作成されると、一貫したスナップショットがPostgresによってエクスポートされます。このスナップショットを使用して、データの一貫した初期コピーを取得できます。 PGDのフェイルオーバースロットメカニズムも同じ手順に従います。ただし、コンシューマは、スロットが最初に作成されたノードと同じノードからスナップショットを取得する必要があります。さらに、同じノードから初期レプリケーションを開始する必要があります。コンシューマがレプリケーションストリームを介して十分な変更を受信すると、フェールオーバースロットはfailover_safe としてマークされます。スロットがfailover_safe としてマークされると、コンシューマはPGDクラスター内の他のノードに安全にフェイルオーバーできます。ただし、他の考慮事項が適用されます。以下を参照してください。

スロットがfailover_safe かどうかを確認するには、bdr.failover_replication_slots カタログを照会し、指定されたスロットのfailover_safe 列の値を確認できます。

スロットがfailover_safe とマークされる前に、コンシューマが他のPGDノードに接続し、レプリケーションを開始しようとすると、PGDによって適切なエラーが発生します。

新しく参加したノードへのフェイルオーバー#

新しいノードがPGDクラスターに参加すると、CDCフェールオーバースロットのデコードターゲットとして機能する準備がすぐに整わない場合があります。新しく参加したノードには、コンシューマがまだ使用していない変更をデコードするためのすべてのWALファイルがない場合があります。このようなノードから消費すると、データの損失が発生する可能性があります。 PGDは、レプリケーションの進行状況を内部で追跡し、安全なまで新しいノードがフェールオーバーターゲットになるのを防ぐことにより、このような状況を検出して防止します。コンシューマが、デコードターゲットとして機能する準備がまだ整っていないノードに接続しようとすると、適切なエラーが発生します。

オリジンごとの進行状況の追跡#

トランザクションは、PGDクラスター内の任意のノードから発生できます。コンシューマがPGDノードに接続し、トランザクションのデコードを開始すると、そのノードで発生したトランザクションと、クラスター内の他のノードからレプリケートされたトランザクションの変更を受信する場合があります。コンシューマは、このようなすべてのPGDノードまたはオリジンにわたってレプリケーションの進行状況を追跡し、重複したトランザクションが正しく処理されることを確認することが求められます。これを促進するために、Postgres-ExtendedおよびEnterpriseDB Advance Serverのtest_decoding プラグインが機能強化され、トランザクションの起点情報が含まれるようになりました。コンシューマは、論理レプリケーションの開始時にinclude-origin オプションをon に設定することにより、オリジン情報を受信することを選択できます。

以下は、起点情報を含むtest_decoding プラグインのサンプル出力です。

BEGIN 1723654 (origin 2) (origin_name bdr_bdrdemo_bdrgroup_node2) (origin_lsn 0/1D948910)
table public.pgbench_accounts: UPDATE: old-key: aid[integer]:39958 bid[integer]:1 abalance[integer]:0 filler[character]:                                                                                     new-tuple: aid[integer]:39958 bid[integer]:1 abalance[integer]:-1783 filler[character]:
table public.pgbench_tellers: UPDATE: old-key: tid[integer]:6 bid[integer]:1 tbalance[integer]:0 new-tuple: tid[integer]:6 bid[integer]:1 tbalance[integer]:-1783 filler[character]:null
table public.pgbench_branches: UPDATE: old-key: bid[integer]:1 bbalance[integer]:0 new-tuple: bid[integer]:1 bbalance[integer]:-1783 filler[character]:null
table public.pgbench_history: INSERT: tid[integer]:6 bid[integer]:1 aid[integer]:39958 delta[integer]:-1783 mtime[timestamp without time zone]:2025-01-31 16:51:21.511571 filler[character]:null
COMMIT 1723654 (origin 2) (origin_name bdr_bdrdemo_bdrgroup_node2) (origin_lsn 0/1D948910)

コンシューマはこの情報を利用して、オリジンごとの進行状況を追跡できます。

PGDは、bdr.logical_checkpoints カタログ内のすべてのノードにわたるレプリケーションの進行状況も記録し、コンシューマはカタログのデコードされた変更を受信し、その情報を使用してレプリケーションの進行状況を知ることができます。

​​BEGIN 65720
id[name]:370098259-0-6056978 origin_node[oid]:370098259 origin_lsn[pg_lsn]:0/6056978 local_node[oid]:370098259 local_lsn[pg_lsn]:0/6056978 peer_count[integer]:2 peer_nodes[oid[]]:{2228531844,4052927809} peer_lsns[pg_lsn[]]:{0/4836758,0/67F0AF8}
COMMIT 65720

この例では、ノード370098259がレプリケーションの進行状況を報告しています。コンシューマがこの変更レコードを受信すると、ノード2228531844および4052927809からそれぞれ0/4836758および0/67F0AF8までのすべてを受信したことを確認できます。

制限事項#

CDCフェールオーバースロットのサポートには、特定の制限があります。

  • CDCフェールオーバースロットのサポートには、 EDB Postgres DistributedPGD 5.7+の最新バージョンとPostgres ExtendedまたはEDB Postgres Advanced Serverの最新のマイナーリリース2025年2月利用可能が必要です。

  • CDCフェールオーバーのサポートはグローバルオプションであり、スロットごとに設定はできません。 CDCフェールオーバーの有効なステータスの変更は、以前にプロビジョニングされたスロットに影響を与えないため、これを有効にしてglobal に設定し、レプリケートスロットを作成してから無効にしてlocal に設定して、単一のレプリケートスロットを作成することが可能です。

  • CDCフェールオーバーのサポートは、一時的なスロットではサポートされていません。

  • CDCフェールオーバーのサポートは、 failover オプションをfalse に設定して作成されたスロットではサポートされていません。

  • CDCフェールオーバーのサポートは、EDB Postgres Advanced ServerおよびEDB Postgres Extended Serverでのみ動作します。コミュニティPostgresインストールではサポートされていません。

  • オプションが有効になっている場合、既存のスロットはフェールオーバースロットに変換されません。

  • pg_logical_slot_get_changes() などのPostgresのビルトイン機能は使用できますが、スロットが他の場所でデコードされていないことは保証されず、クラスター全体のレプリケーションの進行状況を正確に更新できません。したがって、デコードされた変更を受信するファンクションに依存しないことをお勧めします。