

# RDS for PostgreSQL DB 인스턴스용 액티브-액티브 복제 설정
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication"></a>

다음 절차는 `pgactive`를 사용할 수 있을 때 RDS for PostgreSQL DB 인스턴스 간에 액티브-액티브 복제를 시작하는 방법을 보여 줍니다. 다중 리전 고가용성 예제를 실행하려면 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에서 `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)
   ```

**두 번째 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. 다음 명령을 사용하여 두 번째 RDS for PostgreSQL DB 인스턴스에 데이터베이스를 생성합니다.

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

1. 다음 명령을 사용하여 새 데이터베이스로 연결을 전환합니다.

   ```
   \c app
   ```

1. 기존 데이터베이스에 `pgactive` 확장을 생성합니다.

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

1. 다음 명령을 사용하여 RDS for PostgreSQL 두 번째 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 두 번째 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`는 두 DB 인스턴스 간에 데이터를 동기화합니다.

1. 다음 명령을 사용하여 두 번째 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. 다음 명령을 사용하여 첫 번째 DB 인스턴스에서 두 번째 DB 인스턴스를 분리할 수 있습니다.

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

1. 다음 명령을 사용하여 두 번째 DB 인스턴스에서 `pgactive` 확장을 제거합니다.

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

   확장을 강제로 제거하려면:

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

1. 다음 명령을 사용하여 확장을 제거합니다.

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