Joining additional PGD nodes
============================

このフェーズでは、PGDクラスターを単一ノードを超えて拡張して、高可用機能を有効にし、最終的なアプリケーションのカットオーバーの前に冗長性を確立します。
BDRは外部論理レプリケーションストリームから到着したデータを自動的に転送しないため、ソースノードは独自の専用論理レプリケーションストリームを介して各PGDノードに個別にフィードする必要があります。このアーキテクチャにより、移行中にクラスター全体でデータの一貫性が保証されます。

この手順には、 **物理的結合** と呼ばれる、内部で\ ``pg_basebackup``
を使用する物理コピーを介した高速データ転送が含まれます。このプロセスは、
PGD CLIを介して自動化されています。

PGDパッケージのインストール
---------------------------

追加ノードには、Postgresディストリビューションとバージョンたとえば、EPAS
17の\ ``edb-pgd6-expanded-epas17``
などと一致するPGDパッケージが必要です。続行する前に、適切なPGDリポジトリを構成していることを確認してください。詳細は、
`Installing the database and pgd <https://www.enterprisedb.com/docs/pgd/latest/deploying/deploy-manual/03-installing-database-and-pgd/>`_ を参照してください。

1. BDR拡張機能を有効にするには、Postgres構成を更新してライブラリをプリロードし、シードノードでコミットタイムスタンプを有効にします。

.. code:: bash

       cat >> ${PGDATA}/postgresql.conf <<EOF
       shared_preload_libraries = bdr
       track_commit_timestamp = on
       EOF

1. Postgresを再起動してBDR拡張機能をロードします。

.. code:: bash

       su -u enterprisedb --command "pg_ctl restart"

ソースノードでの追加のレプリケーションスロットの作成
----------------------------------------------------

新しいノードを追加するには、ソースノードに専用のレプリケーションスロットを作成する必要があります。新しいノードのデータを調整するには、シードノードをリファレンスポイントとして使用し、そのレプリケーションを一時的に一時停止して、一貫したスイッチオーバーLSNを確立します。

1. ソースノードで、追加のPGDノードの追加レプリケーションスロットを作成します。

.. code:: sql

       SELECT pg_create_logical_replication_slot(migration_node_${ADD_NODE_PGD_NAME},
           pgoutput);

1. シードノードで、ソースノードからの論理レプリケーションを一時停止します。

.. code:: sql

       ALTER SUBSCRIPTION migration_seed_sub DISABLE;

1. レプリケーションが一時停止しているときに、新しいスロットをシードノードのLSNと合わせて、正確なスイッチオーバーポイントをマークします。ソースノードで、次を実行してスロットを進めます

.. code:: sql

       SELECT pg_replication_slot_advance(migration_node_${ADD_NODE_PGD_NAME},
           (SELECT confirmed_flush_lsn
               FROM pg_replication_slots
               WHERE slot_name = migration_node_${SEED_NODE_PGD_NAME}));

1. ソースノードで、どちらのスロットも進んでいないことを確認しますLSNが静的なままで遅延が増加するはずです。

.. code:: sql

       SELECT slot_name, active, restart_lsn, confirmed_flush_lsn,
           pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS lag_size
       FROM pg_replication_slots;

1. ソースノードで、スタンバイからのアクティブな接続を確認します。シードノードも追加ノードのエントリを表示してはなりません。

.. code:: sql

       SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn,
           pg_size_pretty(pg_wal_lsn_diff(sent_lsn, replay_lsn)) AS replay_lag
       FROM pg_stat_replication;

追加のPGDノードへの参加
-----------------------

PGD CLIは、物理的結合を介してデータ転送プロセスを自動化します。これは、
``pg_basebackup``
を内部で使用して、新しいノードにシードノードのクローンを作成します。

1. 追加のPGDノードで、次を実行します。

.. code:: sql

       su postgres -c pgd node ${ADD_NODE_PGD_NAME} setup      \
           --listen-addr="*"                                    \
           --initial-node-count=3                               \
           --pgdata=${PGDATA}                                   \
           --group-name ${PGD_CLUSTER_NAME}                     \
           --cluster-dsn "${SEED_NODE_DSN}"                     \
           --dsn "${ADD_NODE_DSN}"                              \
           --verbose

1. 完了したら、新しいノードが\ ``ACTIVE``
   であり、シードノードから可視であることを確認します。

.. code:: sql

       SELECT * FROM bdr.node_summary;

..  Warning::
   PGDクラスターがアクティブになり、ほとんどのDDL操作を含むすべての変更をレプリケートします。ノード固有の操作を実行する前にDDLレプリケーション`SET bdr.ddl_replication = off` を無効にして、意図しない伝播を防ぎます。アプリケーションがスイッチオーバーするまで、PGDノードにDML変更を直接適用しないでください。

ソースノードからのレプリケーションの再開
----------------------------------------

両方のノードが同じLSNに同期すると、論理データフローを再開できます。

1. シードノードで、ソースノードからの論理レプリケーションを再度有効にします。

.. code:: sql

       SET bdr.ddl_replication = off;
       ALTER SUBSCRIPTION migration_seed_sub ENABLE;

1. 追加ノードでは、サブスクリプションは物理的参加中に意図的にコピーされません。これを手動で作成し、ソースノードの専用スロットを指す必要があります。

.. code:: sql

       SET bdr.ddl_replication = off;
       CREATE SUBSCRIPTION migration_add_sub
           CONNECTION ${SOURCE_NODE_DSN}
           PUBLICATION migration_seed_pub    -- same publication, can be used multiple times
           WITH (
               enabled = false,
               copy_data = false,
               create_slot = false,
               slot_name = migration_node_${ADD_NODE_PGD_NAME}
           );

1. 追加ノードで、サブスクリプションのテーブルリストが
   :ref:`シードノードへの論理レプリケーションの有効化 <シードノードへの論理レプリケーションの有効化>` で取得した構成と一致することを確認します。

.. code:: sql

       SELECT n.nspname AS schemaname,
           c.relname AS tablename,
           sr.srsubstate AS state,
           s.subname AS subscription_name
       FROM pg_subscription_rel sr
       JOIN pg_class c ON sr.srrelid = c.oid
       JOIN pg_namespace n ON c.relnamespace = n.oid
       JOIN pg_subscription s ON sr.srsubid = s.oid
       WHERE s.subname = migration_seed_sub
       ORDER BY n.nspname, c.relname;

1. 追加ノードで、サブスクリプションを有効にしてソースノードからレプリケーションを再開します。

.. code:: sql

       SET bdr.ddl_replication = off;
       ALTER SUBSCRIPTION migration_seed_sub ENABLE;

すべてのレプリケーションストリームの検証
----------------------------------------

すべてのノードがソースからデータを受信し、PGDクラスター内で通信していることを確認します。データはPGDからソースノードに逆流しないことに注意してください。

1. ソースノードで、次のクエリーを実行して、非PGD論理サブスクリプションラグを確認します。

.. code:: sql

       SELECT slot_name, active, confirmed_flush_lsn, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) as lag FROM pg_replication_slots;

PGDノードごとに1つのエントリ、および遅延は最小限であることが予想されます。

1. 各PGDノードで、
   PGDメッシュとレプリケーションのステータスを確認します。
   PGDクラスターのアイドル状態のため、トラフィックは非常に少ないと予想されますが、遅延はありません。

.. code:: sql

       SELECT * FROM bdr.node_summary;
       SELECT * FROM bdr.subscription_summary;
       SELECT * FROM bdr.node_replication_rates;

次のステップ :ref:`Application cutover <Application cutover>`  。
