

# RDS for PostgreSQL DB インスタンスのアクティブ/アクティブレプリケーションの設定
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication"></a>

以下の手順は、`pgactive` が利用可能な場合に 2 つの RDS for PostgreSQL DB インスタンス間でアクティブ/アクティブレプリケーションを開始する方法を示しています。マルチリージョンの高可用性の例を実行するには、2 つの異なるリージョンに Amazon RDS for PostgreSQL インスタンスをデプロイし、VPC ピアリングを設定する必要があります。詳細については、「[VPC ピアリング接続](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html)」を参照してください。

**注記**  
複数のリージョン間でトラフィックを送信すると、追加コストが発生する可能性があります。

次の手順では、RDS for PostgreSQL DB インスタンスが `pgactive` 拡張を使用して有効化されていることを前提としています。詳細については、「[pgactive 拡張機能の初期化](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md)」を参照してください。

**`pgactive` 拡張を使用して最初の RDS for PostgreSQL DB インスタンスを設定するには**

次の例は、`pgactive` グループの作成方法と、RDS for PostgreSQL DB インスタンスで `pgactive` 拡張を作成するために必要なその他の手順を示しています。

1. `psql` または別のクライアントツールを使用して、最初の RDS for PostgreSQL DB インスタンスに接続します。

   ```
   psql --host=firstinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password=PASSWORD --dbname=postgres
   ```

1. 次のコマンドを使用して RDS for PostgreSQL インスタンスにデータベースを作成します。

   ```
   postgres=> CREATE DATABASE app;
   ```

1. 次のコマンドを使用して、接続先を新しいデータベースに切り替えます。

   ```
   \c app
   ```

1. 次の SQL ステートメントを使用して、サンプルのテーブルを作成および設定します。

   1. 次の SQL ステートメントを使用してサンプルテーブルを作成します。

      ```
      app=> CREATE SCHEMA inventory;
      CREATE TABLE inventory.products (
      id int PRIMARY KEY, product_name text NOT NULL,
      created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP);
      ```

   1. 次の SQL ステートメントを使用して、サンプルデータをテーブルに入力します。

      ```
      app=> INSERT INTO inventory.products (id, product_name)
      VALUES (1, 'soap'), (2, 'shampoo'), (3, 'conditioner');
      ```

   1. 次の SQL ステートメントを使用して、テーブルにデータが存在することを確認します。

      ```
       app=>SELECT count(*) FROM inventory.products;
      
       count
      -------
       3
      ```

1. 既存のデータベースで `pgactive` 拡張を作成します。

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. pgactive グループを安全に作成して初期化するには、以下のコマンドを使用します。

   ```
   app=>
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
         -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   これで、レプリケーショングループを初期化し、この最初のインスタンスを追加できます。

   ```
   SELECT pgactive.pgactive_create_group(
       node_name := 'endpoint1-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   
   );
   ```

   代替手段として、以下のコマンドを使用して pgactive グループを作成および初期化します。ただし、安全性は低くなります。

   ```
   app=> SELECT pgactive.pgactive_create_group(
       node_name := 'node1-app',
       node_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD');
   ```

   node1-app は、`pgactive` グループ内のノードを一意に識別するために割り当てる名前です。
**注記**  
パブリックにアクセス可能な DB インスタンスで、このステップを正常に実行するには、`rds.custom_dns_resolution` パラメータを `1` に設定して有効にする必要があります。

1. DB インスタンスの準備が整っているかどうかを確認するには、次のコマンドを使用します。

   ```
   app=> SELECT pgactive.pgactive_wait_for_node_ready();
   ```

   コマンドが正常に完了した場合は、次の出力が表示されます。

   ```
   pgactive_wait_for_node_ready 
   ------------------------------ 
   (1 row)
   ```

**2 番目の RDS for PostgreSQL インスタンスを設定して `pgactive` グループに参加させるには**

次の例は、RDS for PostgreSQL DB インスタンスを `pgactive` グループに参加させる方法と、DB インスタンスに `pgactive` 拡張を作成するために必要なその他のステップを示しています。

次の手順では、RDS for PostgreSQL DB インスタンスが `pgactive` 拡張を使用して設定されていることを前提としています。詳細については、「[pgactive 拡張機能の初期化](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md)」を参照してください。

1. `psql` を使用して、パブリッシャーから更新を受け取るインスタンスに接続します。

   ```
   psql --host=secondinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password=PASSWORD --dbname=postgres
   ```

1. 次のコマンドを使用して、2 番目の RDS for PostgreSQL DB インスタンスにデータベースを作成します。

   ```
   postgres=> CREATE DATABASE app;
   ```

1. 次のコマンドを使用して、接続先を新しいデータベースに切り替えます。

   ```
   \c app
   ```

1. 既存のデータベースに `pgactive` 拡張を作成します。

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. 次に示すように、以下のコマンドを使用して、より安全な方法で RDS for PostgreSQL の 2 番目の DB インスタンスを `pgactive` グループに参加させます。

   ```
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
   
   -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   ```
   SELECT pgactive.pgactive_join_group(
       node_name := 'endpoint2-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint2',
       join_using_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   );
   ```

   代替手段として、以下のコマンドを使用して RDS for PostgreSQL の 2 番目の DB インスタンスを `pgactive` グループに参加させます。ただし、安全性は低くなります。

   ```
   app=> SELECT pgactive.pgactive_join_group(
   node_name := 'node2-app',
   node_dsn := 'dbname=app host=secondinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD',
   join_using_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD');
   ```

   node2-app は、`pgactive` グループ内のノードを一意に識別するために割り当てる名前です。

1. DB インスタンスの準備が整っているかどうかを確認するには、次のコマンドを使用します。

   ```
   app=> SELECT pgactive.pgactive_wait_for_node_ready(); 
   ```

   コマンドが正常に完了すると、次の出力が表示されます。

   ```
   pgactive_wait_for_node_ready 
   ------------------------------ 
   (1 row)
   ```

   最初の RDS for PostgreSQL データベースが比較的大きい場合は、`pgactive.pgactive_wait_for_node_ready()` から復元操作の進行状況レポートを出力されることを確認できます。出力は次の例のようになります:

   ```
   NOTICE:  restoring database 'app', 6% of 7483 MB complete
   NOTICE:  restoring database 'app', 42% of 7483 MB complete
   NOTICE:  restoring database 'app', 77% of 7483 MB complete
   NOTICE:  restoring database 'app', 98% of 7483 MB complete
   NOTICE:  successfully restored database 'app' from node node1-app in 00:04:12.274956
    pgactive_wait_for_node_ready 
   ------------------------------ 
   (1 row)
   ```

   この時点から、`pgactive` は 2 つの DB インスタンス間でデータを同期します。

1. 次のコマンドを使用して、2 番目の DB インスタンスのデータベースにデータがあるかどうかを確認できます。

   ```
   app=> SELECT count(*) FROM inventory.products;
   ```

   データが正常に同期されると、次の出力が表示されます。

   ```
    count
   -------
    3
   ```

1. 次のコマンドを実行して新しい値を挿入します。

   ```
   app=> INSERT INTO inventory.products (id, product_name) VALUES (4, 'lotion');
   ```

1. 最初の DB インスタンスのデータベースに接続し、次のクエリを実行します。

   ```
   app=> SELECT count(*) FROM inventory.products;
   ```

   アクティブ/アクティブレプリケーションが初期化されると、出力は次のようになります。

   ```
   count
   -------
    4
   ```

**`pgactive` グループから DB インスタンスをデタッチして削除するには**

`pgactive` グループから DB インスタンスをデタッチして削除するには、次の手順に従います。

1. 次のコマンドを使用して、最初のインスタンスから 2 番目の DB インスタンスをデタッチできます。

   ```
   app=> SELECT * FROM pgactive.pgactive_detach_nodes(ARRAY[‘node2-app']);
   ```

1. 次のコマンドを使用して、2 番目の DB インスタンスから `pgactive` 拡張を削除します。

   ```
   app=> SELECT * FROM pgactive.pgactive_remove();
   ```

   拡張を強制的に削除するには

   ```
   app=> SELECT * FROM pgactive.pgactive_remove(true);
   ```

1. 次のコマンドを使用して拡張をドロップします。

   ```
   app=> DROP EXTENSION pgactive;
   ```