Node management

PGDグループのメンバーである各データベースは、独自のノードで表される必要があります。ノードは、PGDグループ内のデータベースの一意の識別子です。

現在、各ノードは1つのノードグループのみのメンバーになれます。 (これは後のリリースで拡張される可能性があります。)各ノードは1つ以上のレプリケーションセットにサブスクライブして、レプリケーションをきめ細かく制御できます。

PGDグループには0個以上のサブグループが含まれる場合があり、さまざまな異なるアーキテクチャを作成できます。

PGDグループの作成と参加

PGDの場合、すべてのノードは他のすべてのノードに接続する必要があります。構成を簡単にするために、新しいノードが参加すると、既存のすべてのノードが接続するように構成されます。このため、作成された最初のPGDノードを含むすべてのノードは、他のノードが接続に使用できる

PostgreSQL connection string

(データソース名(DSN)とも呼ばれます)を知っている必要があります。接続文字列の両方の形式がサポートされています。したがって、 host=myhost port=5432 dbname=mydb のようなキー値形式、またはpostgresql://myhost:5432/mydb のようなURI形式のいずれかを使用できます。

SQL関数 bdr.create_node_group() は、ローカルノードからPGDグループを作成します。これにより、そのノードでPGDがアクティブになり、他のノードがその時点で1つのノードのみで構成されるPGDグループに参加できるようになります。作成時には、他のノードがこのノードに接続するために使用する接続文字列を指定する必要があります。

ノードグループが作成されると、以降のすべてのノードは bdr.join_node_group() 関数を使用してPGDグループに参加できます。

または、コマンドラインユーティリティ

bdr_init_physical を使用して、既存のノードのpg_basebackup

(またはフィジカルスタンバイ)を使用して新しいノードを作成します。 pg_basebackup を使用している場合、 bdr_init_physicalユーティリティは、オプションでターゲットデータベースのみのベースバックアップを指定できます。以前の動作は、データベースクラスター全体をバックアップすることでした。このユーティリティを使用すると、アクティビティはより速く完了し、不要なデータベースを除外するため、使用する領域も少なくなります。ターゲットデータベースのみを指定すると、除外されたデータベースがクリーンアップされ、新しいノードで削除されます。

新しいPGDノードが既存のPGDグループに参加する場合、またはノードがアップストリームピアにサブスクライブする場合、レプリケーションを開始する前に、システムは既存のデータをピアノードからローカルノードにコピーする必要があります。このコピーは、ローカルデータとリモートデータが最初は同じになるように慎重に調整する必要があります。自分でpg_dumpを使用するだけでは不十分です。 BDR拡張機能は、この初期コピーを作成するための組み込み機能を提供します。

参加プロセス中に、 BDR拡張機能は、提供されたソースノードを基礎として使用して既存のデータを同期し、PGDグループのメッシュトポロジで自分自身を確立するために必要なすべてのメタデータ情報を作成します。この初期コピー中にソースと新しいノード間の接続が切断された場合は、参加プロセスを最初からやり直します。

クラスターに参加するノードには、PGDグループのデータベースに既に存在するスキーマまたはデータが含まれていてはなりません。 BDR拡張子を除き、新しく参加するデータベースは空にすることをお勧めします。ただし、必要なすべてのデータベースユーザーとロールが作成されていることが重要です。

オプションで、 bdr.join_node_group ファンクションのsynchronize_structure パラメーターを使用して、スキーマの同期をスキップできます。この場合、スキーマは新しく参加するノードにすでに存在している必要があります。

参加するソースノードとして、接続が最適な(最も近い)ソースノードを選択することをお勧めします。そうすることで、結合が完了するまでに必要な時間が短縮されます。

Raftコンセンサスアルゴリズムを使用して、参加手順を調整します。これには、ほとんどの既存のノードがオンラインで到達可能であることが必要です。

論理結合プロシージャ( bdr.join_node_group ファンクションを使用する)は、 COPY 操作を実行してデータ同期を実行し、有効になっている場合は複数のライター(並列適用)を使用します。

ノードジョインは、ジョインにかかる時間の大部分を他のノードジョインと同時に実行できます。ただし、一度に1つの通常ノードのみが状態PROMOTEまたはPROMOTINGのいずれかになります。これは、他のすべてのノードが稼働している場合、通常はかなり短くなります。それ以外の場合、結合はこの段階でシリアル化されます。サブスクライバー専用ノードはこのルールの例外であり、同時にPROMOTEおよびPROMOTING状態になる可能性があるため、参加プロセスは完全に同時です。

参加プロセスはソースとして1つのノードのみを使用するため、ノードの過半数が利用可能な場合、ノードがダウンしたときに実行できます。これにより、論理結合の実行が複雑になる可能性があります。論理結合中に、ソースノードからコピーされた行のコミットタイムスタンプは、ソースノードの最新のコミットタイムスタンプに設定されます。これより前のコミットタイムスタンプを持つノードでコミットされた変更(ノードがダウンしているか、大幅なラグがあるため)は、他のノードからの変更と競合する可能性があります。この場合、新しく参加したノードは他のノードとは異なる方法で解決される可能性があり、発散が発生します。その結果、ノード間に重大なレプリケーションラグが存在する場合は、ノード参加を実行しないことをお勧めします。これが必要な場合は、新しく参加したノードでLiveCompareを実行して、すべてのノードが利用可能で追いついたら、データの相違を修正します。

pg_dump は、キャッシュルックアップの失敗が原因で、ソースノードで同時DDLアクティビティがある場合に失敗する可能性があります。

bdr.join_node_group は内部でpg_dump

を使用するため、ソースノードに同時DDLアクティビティがあると失敗する場合があります。その場合、結合を再試行すると機能します。

異種クラスターへの参加

PGD 4.0ノードは、特定の最小メンテナンスリリース(3.7.6など)または3.7と4.0ノードの混合で3.7.xを実行しているEDB Postgres分散クラスターに参加できます。この手順は、PGDメジャーバージョンだけでなく、基になるPostgreSQLメジャーバージョンもアップグレードする場合に役立ちます。これを実現するには、PostgreSQL 12または13で実行されている3.7ノードをPostgreSQL 11で3.6.xを実行しているEDB Postgres分散クラスターに参加させます。 新しいノードは、既存のクラスター内のすべてのノードと同じPostgreSQLメジャーリリースで実行することもできます。

PGDは、一部のノードが1つのPostgreSQLメジャーリリースで3.6を実行していて、他のノードが別のPostgreSQLメジャーリリースで3.7を実行している場合でも、レプリケーションがすべての方向で正しく機能することを保証します。ただし、十分な数の新しいノードがクラスターに参加したら、古いノードを分割することにより、クラスターをすばやく同種の状態にすることをお勧めします。古いバージョンで利用できない可能性のあるDDL、またはその逆を実行しないでください。

PostgreSQLの別のメジャーリリースに参加するノードは、 bdr_init_physical で取得した物理バックアップを使用できません。ノードは、論理結合方法を使用して参加する必要があります。これは、PostgreSQLのメジャーリリースが互いにディスク上で互換性がないため必要です。

3.7ノードが3.6ノードをソースとして使用してクラスターに参加すると、競合解決などの特定の構成がソースノードからコピーされません。ノードは、クラスターに参加した後に構成する必要があります。

接続DSNとSSL(TLS)

ノードはlibpq を使用して接続するため、ノードのDSNは単なるlibpq 接続文字列です。そのため、SSL用のパラメーターを含む、許可されたlibpq 接続パラメーターを含めることができます。 DSNは、指定されたノードに接続するクライアントからの接続文字列として機能する必要があります。クライアント証明書を使用するこのようなパラメーターのセットの例は次のとおりです。

sslmode=verify-full sslcert=bdr_client.crt sslkey=bdr_client.key
sslrootcert=root.crt

このセットアップでは、ファイルbdr_client.crt 、bdr_client.key 、およびroot.crt が、適切な権限を持つ各ノードのデータディレクトリに存在する必要があります。 verify-full モードの場合、サーバーのSSL証明書がチェックされ、 root.crt 認証局で直接または間接的に署名されていること、および接続で使用されるホスト名またはアドレスが証明書の内容と一致することを確認します。名前の場合、これはサブジェクトの別名と一致するか、証明書にそのような名前がない場合はサブジェクトの共通名(CN)フィールドと一致します。 Postgresは現在、IPアドレスのサブジェクトの別名をサポートしていないため、名前ではなくアドレスで接続が行われる場合、 CNフィールドと一致する必要があります。

クライアント証明書のCNは、PGD接続を行うユーザーの名前である必要があります。これは通常、ユーザーpostgresです。各ノードには、 pg_hba.conf ファイルでの接続を許可する一致する行が必要です。例:

hostssl all         postgres 10.1.2.3/24 cert
hostssl replication postgres 10.1.2.3/24 cert

別のセットアップは、クライアント証明書の代わりにSCRAM-SHA-256 パスワードを使用し、証明書が適切に署名されている限りサーバーIDを検証しないことです。ここでDSNパラメーターは次のようになります。

sslmode=verify-ca sslrootcert=root.crt

対応するpg_hba.conf 行は次のとおりです。

hostssl all         postgres 10.1.2.3/24 scram-sha-256
hostssl replication postgres 10.1.2.3/24 scram-sha-256

このようなシナリオでは、 postgresユーザーは正しいパスワードを含む.pgpass ファイルを必要とします。

Witnessノード

クラスターのノード数が偶数の場合、ネットワーク分割(またはネットワークパーティションと呼ばれることもあります)が発生した場合に関係を断ち切るのに役立つ追加のノードを作成すると役立つ場合があります。

追加のフルサイズのノードを作成する代わりに、監視ノードと呼ばれるマイクロノードを作成できます。これは、テーブルまたはデータを複製しないように意図的に設定された通常のPGDノードです。

ロジカルスタンバイノード

PGDを使用すると、オフロードノード、読み取り専用ノード、受信専用ノード、または論理読み取りレプリカとも呼ばれる 論理スタンバイノード を作成できます。マスターノードは、ゼロ、1つ以上のロジカルスタンバイノードを持つことができます。

注釈

ロジカルスタンバイノードは、データセンター間のネットワークトラフィックが懸念される環境で使用できます。それ以外の場合、場所ごとにより多くのデータノードを持つことが常に好まれます。

フィジカルスタンバイノードでは、ノードが完全に起動しないため、継続的リカバリモードのままになります。 PGDは似たようなことを許可します。

bdr.join_node_group には、ノードをロジカルスタンバイノードとして途中で結合したままにするpause_in_standby

オプションがあります。ロジカルスタンバイノードは変更を受け取りますが、ローカルで行われた変更を他のノードに送信しません。

後で、必要に応じて bdr.promote_node を使用して、ロジカルスタンバイをフルの通常の送信/受信ノードに移動します。

ロジカルスタンバイには、 bdr.join_node_group のDSNで定義された1つのソースノードからデータが送信されます。他のすべてのノードからの変更はこの1つのソースノードから受信され、複数のサイト間の帯域幅を最小限に抑えます。

高可用性には複数のオプションがあります。

  • ソースノードが死亡した場合、1つのフィジカルスタンバイをマスターに昇格できます。この場合、新しいマスターは、任意またはすべてのロジカルスタンバイノードに電力を供給し続けることができます。

  • ソースノードが停止した場合、1つのロジカルスタンバイをフルノードに昇格させ、シングルマスター操作と同様のフェールオーバー操作でソースを置き換えることができます。複数のロジカルスタンバイノードがある場合、他のノードは新しいマスターをフォローできないため、この手法の有効性は1つのロジカルスタンバイに制限されます。

既存のPGDノードから新しいスタンバイが作成された場合、操作に必要なレプリケーションスロットは、グループスロットが最後に進められてから少なくとも16 MBのLSNが経過するまで、新しいスタンバイに同期されません。極端な場合、これには、スロットがストリーミングレプリカで同期または作成される前に、完全な16 MBが必要になる場合があります。この間隔中にフェールオーバーまたはスイッチオーバーが発生した場合、グループスロットと他の依存スロットがまだ存在しないため、ストリーミングスタンバイをそのPGDノードを置き換えるように昇格させることはできません。

スタンバイのスロット同期アッププロセスは、アップストリームの関数を呼び出すことによりこれを解決します。この機能は、WALスイッチを実行し、すべてのPGDピアノードに進行状況の更新を再生するように要求することにより、 EDB Postgres分散クラスター全体のグループスロットを移動します。これにより、グループスロットが短時間で先に進みます。これにより、スタンバイが最初のスロットの同期に必要な時間が短縮され、必要に応じて初期スロットへのフェールオーバーが高速化されます。

PostgreSQLでは、昇格する前に、スロットの同期がスタンバイで完了していることを確認することが重要です。ターゲットデータベースのスタンバイで次のクエリを実行して、スロットがアップストリームと同期していることを監視および確認できます。このクエリがtrue を返すと、プロモーションを進めることができます。

SELECT true FROM pg_catalog.pg_replication_slots WHERE
    slot_type = logical AND confirmed_flush_lsn IS NOT NULL;

WALスイッチを手動で実行し、すべてのPGDピアノードに進行状況の更新を再生するように要求することにより、PGDクラスター全体でスロット同期プロセスを微調整することもできます。このアクティビティにより、グループスロットが短時間で先に進み、スタンバイでのスロット同期アクティビティが早められます。このために、ターゲットデータベース内のPGDピアノードで次のクエリを実行できます。

SELECT bdr.run_on_all_nodes(SELECT pg_catalog.pg_switch_wal());
SELECT bdr.run_on_all_nodes(SELECT bdr.request_replay_progress_update());

スタンバイでモニタリングクエリを使用して、これらのクエリがそのスタンバイでのスロット同期の高速化に役立つことを確認します。

ロジカルスタンバイノードは、必要に応じてフィジカルスタンバイノードを使用して保護できるため、 Master->LogicalStandby->PhysicalStandby。 LogicalStandbyからLogicalStandbyにカスケードすることはできません。

ロジカルスタンバイでは書き込みトランザクションが許可されるため、フィジカルスタンバイの制限は適用されません。これを使用すると、ロジカルスタンバイに追加のインデックス、データ、中間作業表、LISTEN/NOTIFY、一時テーブル、マテリアライズドビュー、およびその他の違いのより長い保持期間を設定できるため、大きなメリットがあります。

昇格前にコミットされたロジカルスタンバイに対してローカルに行われた変更は、他のノードに送信されません。昇格後にコミットされるすべてのトランザクションは、以降に送信されます。ロジカルスタンバイへの書き込みを実行する場合は、昇格する前にデータベースを静止するように注意してください。

ロジカルスタンバイノードにDDL変更を加える場合がありますが、それらはレプリケートされず、グローバルDDLロックを取得しようとしません。 DDLと同様に動作するPGD関数もレプリケートされません。

DMLおよびDDLレプリケーション を参照してください。ロジカルスタンバイに互換性のないDDL変更を加えた場合、データベースは

ダイバージェントノード です。現在、発散ノードの昇格はレプリケーションに失敗します。その結果、ロジカルスタンバイノードをスタンバイとして使用する場合は、ロジカルスタンバイノードが発散の変更を受けないようにするか、発散ノードが昇格しないことを保証することを計画してください。

フィジカルスタンバイノード

PGDでは、従来のフィジカルスタンバイフェールオーバーノードを作成することもできます。これらは一般に、短い昇格手順の後、クラスター内のPGDノードを直接置き換えることを目的としています。標準のPostgresクラスターと同様に、ノードはこれらの物理レプリカを任意の数持つことができます。

ただし、PGDでのレプリケーションスロットおよびその他の機能要件の使用により、これが適切に機能するための最小前提条件がいくつかあります。

  • PGDプライマリとスタンバイ間の接続は、物理レプリケーションスロットを介したストリーミングレプリケーションを使用します。

  • スタンバイには以下があります。 - recovery.conf (PostgreSQL <12の場合、PostgreSQL 12+の場合、これらの設定はpostgres.conf にあります): - プライマリを指すprimary_conninfo :- shared_preload_libraries = 'bdr' 、リストには他のプラグインもありますが、 pglogicalを含めないでください - hot_standby = on - hot_standby_feedback = on

  • プライマリには以下があります。 - postgresql.conf : - bdr.standby_slot_names は、スタンバイのprimary_slot_name に使用される物理レプリケーションスロットを指定します。

PGDノードの動作中のフィジカルスタンバイを生成するにはこれで十分ですが、いくつかの追加の問題に対処する必要があります。

確立されると、スタンバイは、PGDグループスロットを含むプライマリの他のPGD関連のレプリケーションスロットの初期コピーをトリガーするのに十分な時間とWALトラフィックを必要とします。少なくとも、スタンバイ上のスロットはライブであり、 pg_replication_slots によって報告されるようにゼロ以外のconfirmed_flush_lsn を報告する場合にのみ、フェイルオーバー後も生き残ることができます。

その結果、フェールオーバーが正常に動作すると想定する前に、書き込みアクティビティの量が少ない新しく初期化されたPGDクラスターのフィジカルスタンバイノードを確認します。この予防措置を講じないと、スタンバイがPGDノードとして機能するために必要なレプリケーションスロットの不完全なサブセットを保持し、フェールオーバーが中止される可能性があります。

フィジカルスタンバイノードが最新の状態であり、昇格できることを保証する保護メカニズム(

bdr.standby_slot_names

で構成)は、PGDグループの全体的なレプリケーションレイテンシーに影響します。これは、グループレプリケーションがフィジカルスタンバイノードが最新の場合にのみ発生するためです。

これらの理由から、通常、フィジカルスタンバイノードではなく、ロジカルスタンバイノードまたはサブスクライブ専用グループのいずれかを使用することをお勧めします。どちらも比較すると運用特性が優れています。

すべてのノードでグループスロットが(可能な限り)拡張されていることを手動で確認できます。これにより、次のSQL構文を使用して、フィジカルスタンバイでのPGD関連のレプリケーションスロットの作成を促進できます。

SELECT bdr.move_group_slot_all_nodes();

フェールオーバー時に、スタンバイは2つのアクションのいずれかを実行してプライマリを置き換える必要があります。

  • プライマリと同じIPアドレスまたはホスト名の制御を引き受けます。

  • 他のすべてのPGDノードで bdr.alter_node_interface ファンクションを実行して、アドレスの変更をEDB Postgres分散クラスターに通知します。

これが完了すると、他のPGDノードは、新しく昇格したスタンバイ->プライマリノードとの通信を再確立します。レプリケーションスロットは定期的にのみ同期されるため、この新しいプライマリは、既存のPGDノードで予想されるよりも低いLSNを反映する場合があります。この場合、PGDは各遅延スロットを各PGDノードが使用した最後の場所に早送りします。

)パラメーターにも特に注意してください。プライマリ->フィジカルスタンバイの関係があるEDB Postgres分散クラスターで、またはサブスクライバー専用グループを使用する場合は、それを設定することが重要です。

PGDは、アウトバウンドレプリケーションで最も遅延が大きいクラスターノードの状態を常に反映するグループスロットを維持します。物理レプリカを追加すると、グループスロットの状態に関係なく、参加していないノードメンバーがあることをPGDに通知する必要があります。

スタンバイは他のPGDノードと直接通信しないため、 standby_slot_names パラメーターは、グループスロットの必要な制約として名前付きスロットを考慮するようにPGDに通知します。設定すると、グループスロットが正常に進んでいても、スタンバイに遅れが見られる場合はグループスロットが保持されます。

他の物理レプリカと同様に、このタイプのスタンバイは同期レプリカとして構成することもできます。なお、これには以下が必要です。

  • スタンバイ: - primary_conninfo にユニークなapplication_name を指定

  • プライマリで: - synchronous_commit を有効にする - synchronous_standby_names にスタンバイapplication_name を含める

synchronous_standby_names にフィジカルスタンバイノードと他のPGDノードを混在させることができます。 CAMOとEager All-Node Replicationは異なる同期メカニズムを使用し、同期レプリケーションでは動作しません。 CAMOまたはEager All-Node Replicationのいずれかを使用する場合、 synchronous_standby_names にPGDノードが含まれていないことを確認してください。代わりに、フィジカルスタンバイなどの非PGDノードのみを使用します。

サブグループ

グループには、ゼロ個以上のサブグループを含めることもできます。各サブグループは、最上位の親グループで特定の目的に割り当てることができます。 node_group_typeは、サブグループが作成されるときにタイプを指定します。

購読者専用グループ

名前が示すように、このタイプのノードは、クラスター内の他のノードからのレプリケーションの変更のみにサブスクライブします。ただし、他のノードはsubscriber-only ノードからレプリケーションの変更を受け取りません。これは、ロジカルスタンバイノードに多少似ています。ただし、ロジカルスタンバイとは対照的に、 subscriber-only ノードはクラスターに完全に参加しています。彼らはクラスター内の他のすべてのノードからレプリケーションの変更を受け取ることができるため、クラスター内の1つのノードの非可用性または分離の影響を受けません。

subscriber-only ノードは完全に参加したPGDノードであるため、複製されたすべてのDDLを受信し、それらに動作します。また、Raftを使用して、クラスター内のすべてのノードにステータスを一貫して報告します。 subscriber-only ノードにはRaftの投票権がないため、Raftリーダーになることも、リーダー選挙に参加することもできません。また、レプリケートされたDDLを受信しますが、 DDLまたはDMLロックの取得には参加しません。言い換えれば、現在ダウンしているsubscriber-only ノードは、DMLロックの取得を停止しません。

subscriber-only ノードは、PGDツリートポロジのビルディングブロックを形成します。このトポロジでは、少数の完全にアクティブなノードがすべての方向に変更をレプリケートしています。多数のsubscriber-only ノードは変更のみを受け取りますが、クラスター内の他のノードに変更を送信することはありません。このトポロジは、多数のノードによる接続の爆発を回避しますが、データの消費に使用できる非常に多数のleaf ノードを提供します。

subscriber-only ノードを利用するには、最初にsubscriber-only タイプのPGDグループを作成します。メンバーノードがレプリケーションの変更を受け取るグループのサブグループにします。サブグループを作成したら、 subscriber-only ノードになる予定のすべてのノードはサブグループに参加する必要があります。 subscriber-only タイプのサブグループを複数作成でき、異なる親グループを持つことができます。

ノードがsubscriber-only サブグループに正常に参加すると、それはsubscriber-only ノードになり、親グループのレプリケーション変更の受信を開始します。 subscriber-only ノードで直接行われた変更は複製されません。

特定のタイプのサブグループを作成し、特定の親グループに属する方法については、

bdr.create_node_group を参照してください。

注意事項

subscriber-only ノードはクラスター内のノードに変更をレプリケートしないため、ノードがクラスターから分離されると、レプリケーションの変更を同期するソースとして機能できません。ただし、 subscriber-only ノードがすでにクラスター内の他のノードが持っていない分離されたノードからレプリケーションの変更を受信して適用している場合、ノード間で矛盾が発生します。

今のところ、 bdr.standby_slot_names を設定することでこれを解決できます

および bdr.standby_slots_min_confirmed により、 subscriber-only ノードよりも前に完全にアクティブなPGDノードが常に存在します。

デコードワーカー

PGD4は、データが送信されるノードの数に関係なく、1回のデコードを実行するデコードワーカープロセスを有効にするオプションを提供します。これにより、各PGDノードに新しいプロセス、WALデコーダーが導入されます。接続ごとに1つのWAL送信プロセスが引き続き存在しますが、これらのプロセスはデータの送受信のタスクのみを実行するようになりました。まとめると、これらの変更は、より大きなPGDグループのCPUオーバーヘッドを削減し、WAL送信者プロセスが通信により多くの時間を費やすようになったため、レプリケーションスループットを向上させます。

enable_wal_decoder は各PGDグループのオプションであり、現在デフォルトで無効になっています。

bdr.alter_node_group_config()を使用したグループ構成 を使用して、PGDグループのデコードワーカーを有効または無効にすることができます。

デコードワーカーが有効になっている場合、PGDは論理変更レコード(LCR)ファイルを保存して、デコードとすべてのサブスクライブノードがデータを受信したときとの間の変更をバッファリングできるようにします。 LCRファイルは、各ローカルノードのデータディレクトリのpg_logical ディレクトリの下に保存されます。レプリケーションラグが増加すると、LCRファイルの数とサイズが変化するため、これも監視が必要です。 PGDノードのいずれかで必要とされないLCRは、定期的にクリーニングされます。 2つの連続するクリーンアップの間隔は bdr.lcr_cleanup_interval によって制御され、デフォルトは3分です。

bdr.lcr_cleanup_interval がゼロの場合、クリーンアップは無効になります。

無効にすると、各ノードにサブスクライブしている各ノードのWAL送信者プロセスによって論理デコードが実行されます。この場合、LCRファイルは書き込まれません。

PGDグループのデコードワーカーが有効になっている場合でも、次のGUCはノードごとのLCRの生成と使用を制御します。デフォルトでは、これらはfalse です。 LCRの生成と使用には、PGDグループのデコードワーカーを有効にし、これらのGUCをPGDグループ内の各ノードでtrue に設定します。

  • bdr.enable_wal_decoder — false にすると、LCRを使用するすべてのWAL送信者は再起動してWALを直接使用します。 PGDグループ構成とともにtrue を使用すると、デコードワーカープロセスが開始されてLCRが生成され、WAL送信者はLCRを使用します。

  • bdr.receive_lcr &mdash;サブスクライブノードでtrue を使用する場合、パブリッシャーノード上のWALセンダーにLCRが利用可能であれば使用するように要求します。

注意事項

現時点では、デコードワーカーは、実行中のノードに対応する変更をデコードします。ロジカルスタンバイには、単一のソースを介してPGDグループ内のすべてのノードから変更が送信されます。したがって、ロジカルスタンバイを提供するWAL送信者は、現在LCRを使用できません。

サブスクライバー専用ノードは、各ノードから直接変更を受け取ります。したがって、加入者専用ノードにサービスを提供するWAL送信者は、LCRを使用できます。

LCRが生成されても、対応するWALは、デコードワーカーが有効になっていない場合と同様に保持されます。将来、特に必要ない場合は、LCRに対応するWALを削除できる可能性があります。

参考までに、LCRファイル名の最初の24文字はWALファイル名と似ています。名前の最初の8文字はすべて「0」です。将来的には、WALセグメントファイル名の最初の8文字に似たTimeLineIdを表すことが期待されます。次の名前の16文字のシーケンスは、WALストリームに対してLCRの変更を追跡するために使用されるWALセグメント番号に似ています。

ただし、論理変更は、それらが属するトランザクションのコミット順序に従って並べ替えられます。したがって、LCRセグメント内のそれらの配置は、WALセグメント内の対応するWALの配置と一致しません。

最後の16文字のセットは、LCRセグメントのサブセグメント番号を表します。各LCRファイルはサブセグメントに対応します。 LCRファイルはバイナリで可変サイズです。 LCRファイルの最大サイズは、 bdr.max_lcr_segment_file_size で制御できます。デフォルトは1 GBです。

ノードの再起動とダウンしたノードの回復

PGDは、ノードの再起動またはノードの切断から回復するように設計されています。切断されたノードは、各ピアノードに再接続し、そのノードから欠落しているデータを複製することにより、グループに再参加します。

ノードが起動すると、各接続はbdr.node_slots.state = catchup で FROM bdr.node_slots; に表示され始め、欠落しているデータの複製を開始します。キャッチアップは、各ピアノードからの欠落データの量に応じて一定期間続き、サーバーのワークロードに応じて、時間の経過とともに増加する可能性があります。

各ノードの書き込みアクティビティの量が均一でない場合、より多くのデータを持つノードからのキャッチアップ期間は、他のノードよりも大幅に長くかかる可能性があります。最終的に、スロットの状態はbdr.node_slots.state = streaming に変わります。

数時間や数日など、長期間オフラインになっているノードは、さまざまな理由でリソースの問題を引き起こし始める可能性があります。次の問題を理解せずに、長期にわたる停止を計画しないでください。

各ノードは変更情報を保持します(1つの replication slot を使用)

ピアノードごと)により、一時的に到達不能なノードへの変更を後でリプレイできます。ピアノードが無期限にオフラインのままである場合、この蓄積された変更情報により、最終的にノードでPostgreSQLトランザクションログ(pg_wal の WAL )のストレージスペースが不足し、データベースサーバーが次のようなエラーでシャットダウンする可能性があります。

PANIC: could not write to file "pg_wal/xlogtemp.559": No space left on device

または、他のディスク不足関連の症状を報告する場合があります。

さらに、オフラインノードのスロットもカタログxminを保持し、カタログテーブルのバキュームを防ぎます。

EDB Postgres Extended ServerおよびEDB Postgres Advanced Serverでは、オフラインノードもデータのフリーズを抑えて、競合解決データの損失を防ぎます(

管理者は、ノードの停止を監視し( Monitoring を参照)、ノードに十分な空きディスク領域があることを確認する必要があります。ワークロードが予測可能な場合は、経時的に使用される領域量を計算できる場合があり、重大な問題が発生する前にノードがダウンできる最大時間を予測できます。

PGDによって作成されたレプリケーションスロットを手動で削除しないでください。その場合、クラスターが損傷し、

PGDによって作成されたレプリケーションスロット

で説明されているように、スロットを使用していたノードをクラスターから分離する必要があります。

ノードがオフラインの間、他のノードはオフラインノードから同じデータセットをまだ受信していない可能性があるため、これはノード間でわずかな相違として表示される場合があります。分割プロセスは、ノード間のこの不均衡を修正します。 (後のバージョンではこれを早く行うかもしれません。)

PGDによって作成されたレプリケーションスロット

PGDマスターノードでは、次のレプリケーションスロットがPGDによって作成されます。

  • bdr_<database name>_<group name> という名前の1つの グループスロット

  • N-1 ノードスロット 、名前付けbdr_<database name>_<group name>_<node name> 、ここでNは、ダイレクトロジカルスタンバイを含む、クラスター内のPGDノードの合計数です。

警告

これらのスロットを削除しないでください。 PGDはそれらを作成および管理し、必要に応じてまたは必要に応じて削除します。

一方、 PGDに影響を与えることなく、ソフトウェア用の適切なコマンドを使用して、 Barmanや論理レプリケーションなどのソフトウェアに必要なレプリケーションスロットを作成または削除できます。他のソフトウェアが使用するスロット名を接頭辞bdr_ で始めないでください。

たとえば、3つのノードalpha 、beta 、およびgamma で構成されるクラスターでは、PGDを使用してmydb データベースを複製し、PGDグループはmygroup と呼ばれます。

  • ノードalpha には3つのスロットがあります。 - bdr_mydb_mygroup という名前の1つのグループスロット - bdr_mydb_mygroup_beta およびbdr_mydb_mygroup_gamma という名前の2つのノードスロット

  • ノードbeta には3つのスロットがあります。 - bdr_mydb_mygroup という名前の1つのグループスロット - bdr_mydb_mygroup_alpha およびbdr_mydb_mygroup_gamma という名前の2つのノードスロット

  • ノードgamma には3つのスロットがあります。 - bdr_mydb_mygroup という名前の1つのグループスロット - bdr_mydb_mygroup_alpha およびbdr_mydb_mygroup_beta という名前の2つのノードスロット

グループレプリケーションスロット

グループスロットは、このノードからのアウトバウンドレプリケーションについて、主にPGDグループ内のノード(すべてのロジカルスタンバイを含む)が追いついた最も古い安全な位置を追跡するためにPGDによって使用される内部スロットです。

グループスロット名は、関数 bdr.local_group_slot_name() によって与えられます。

グループスロットは次のことができます。

  • 既存のすべてのノードを起動して実行せずに(ノードの大部分は稼働している必要がありますが)、新しいノードをPGDグループに参加させます。参加中にダウンしたノードが再び複製を開始した場合にデータ損失を招くことはありません。

  • 一部のノードが分割されたノードに完全に追いついていない場合でも、一貫してクラスターからノードを分割します。

  • いくつかの競合を見逃さないように、フリーズポイントを保持します。

  • タイムスタンプベースのスナップショットの履歴スナップショットを保持します。

グループスロットは通常非アクティブであり、他のノードからのRaft進行状況メッセージに応答して定期的にのみ高速転送されます。

警告

グループスロットを削除しないでください。通常は非アクティブですが、 EDB Postgres分散クラスターの適切なオペレーションには依然として不可欠です。ドロップすると、一部またはすべての機能が動作しなくなったり、誤った結果が発生したりする可能性があります。

長い識別子のハッシュ

レプリケーションスロットの名前は、他のPostgreSQL識別子と同様に、63バイト以下でなければなりません。 PGDは、結果のスロット名がその制限に対して長すぎる場合に、データベース名、PGDグループ名、およびノードの名前を短縮することにより、これを処理します。識別子の短縮は、文字列の最後のセクションを文字列自分自身のハッシュに置き換えることによって実行されます。

たとえば、 group20xxxxxxxxxxxxx (長さ20バイト)という名前のPGDグループを使用して、db20xxxxxxxxxxxxxxxx (長さ20バイト)という名前のデータベースをレプリケートするクラスターについて考えます。 3597186 、be9cbd0 、および7f304a2 は、それぞれdb20xxxxxxxxxxxxxxxx 、group20xxxxxxxxxxxxx 、およびa30xxxxxxxxxxxxxxxxxxxxxxxxxx のハッシュであるため、ノードa30xxxxxxxxxxxxxxxxxxxxxxxxxxx (30バイト長)に関連付けられた論理レプリケーションスロットが呼び出されます。

bdr_db20xxxx3597186_group20xbe9cbd0_a30xxxxxxxxxxxxx7f304a2

PGDグループからノードを削除する

PGDは拡張ノードの停止から回復するように設計されているため、ノードを完全に削除するかどうかをシステムに明示的に伝える必要があります。ノードを完全にシャットダウンし、他のノードに通知しないと、パフォーマンスが低下し、最終的にシステム全体が動作を停止します。

parting とも呼ばれるノードの削除は、 bdr.part_node()

機能。ノードを削除するには、(ノードの作成中に渡された)ノード名を指定する必要があります。削除するノードを含む、PGDグループ内のアクティブなノードから bdr.part_node() ファンクションを呼び出すことができます。

参加手順と同じように、別れはRaftコンセンサスを使用して行われ、動作するにはノードの大部分がオンラインである必要があります。

別れのプロセスはすべてのノードに影響します。ラフトリーダーは、ノード間の投票を管理して、どのノードが分離ノードからの最新のデータを持っているかを確認します。次に、残りのすべてのノードは、最新のノードへのセカンダリの一時的な接続を確立して、欠落しているデータをキャッチできるようにします。

別れたノードはまだPGDに認識されていますが、リソースを消費しません。別れたノードと同じ名前でノードが再度追加される場合があります。まれに、関数

bdr.drop_node()

を使用して、分割されたノードのすべてのメタデータをクリアしたい場合があります。

PGDグループ全体を削除する

PGDグループは通常、場所にマッピングします。ロケーションが展開されなくなったら、そのロケーションのPGDグループも削除する必要がある可能性があります。

削除するPGDグループは空である必要があります。グループを削除する前に、グループ内のすべてのノードを分離する必要があります。

PGDのアンインストール

PGD拡張機能を削除すると、メタデータテーブルを含むノード内のすべてのPGDオブジェクトが削除されます。次のコマンドでこれを行うことができます。

DROP EXTENSION bdr;

データベースがPGD固有のオブジェクトに依存している場合、PGD拡張機能を削除することはできません。例は次のとおりです。

  • SnowflakeId やgalloc などのPGD固有のシーケンスを使用したテーブル

  • CRDTデータ型を使用する列

  • 一部のPGDカタログテーブルに依存するビュー

BDR拡張機能を削除する前に、これらの依存関係を削除してください。たとえば、依存オブジェクトを削除するか、列タイプをPGD以外の同等のものに変更するか、シーケンスタイプをlocal に戻します。

警告

BDR拡張機能は、ノードがPGDノードグループから正常に分離された場合、またはグループ内の最後のノードである場合にのみ削除できます。 PGDメタデータを削除すると、他のノードとの間のレプリケーションが中断されます。

警告

ローカルデータベース内のローカルPGDノードまたはBDR拡張機能をドロップする場合、既存のセッションはまだPGD固有のワークフローを実行しようとして失敗する場合があります。セッションを切断してからクライアントを再接続するか、インスタンスを再起動することにより、問題を解決できます。

bdr.drop_node() 関数もあります。この機能は、別れに困ったときなど、緊急時にのみ使用してください。

PGDトポロジーのリスト

PGDグループのリスト

次の単純なクエリは、現在のノードがメンバーであるすべてのPGDノードグループをリストします。現在、

bdr.local_node_summary から1行のみを返します。

SELECT node_group_name
FROM bdr.local_node_summary;

より複雑なクエリを使用して、各ノードグループの構成を表示できます。

SELECT g.node_group_name
, ns.pub_repsets
, ns.sub_repsets
, g.node_group_default_repset     AS default_repset
, node_group_check_constraints    AS check_constraints
FROM bdr.local_node_summary ns
JOIN bdr.node_group g USING (node_group_name);

PGDグループ内のノードのリスト

次の例に示すように、 FROM bdr.node_summary; ビューから、特定のノードグループ( mygroup`など)内のすべてのノードのリストを抽出できます。

SELECT node_name         AS name
, node_seq_id            AS ord
, peer_state_name        AS current_state
, peer_target_state_name AS target_state
, interface_connstr      AS dsn
FROM bdr.node_summary
WHERE node_group_name = mygroup;

current_state またはtarget_state クエリ列に示されるように、ノードの読み取り専用状態は、 STANDBY として示されます。