

# pgactive를 사용하여 액티브-액티브 복제 지원
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive"></a>

`pgactive` 확장은 액티브-액티브 복제를 사용하여 여러 RDS for PostgreSQL 데이터베이스에서 쓰기 작업을 지원하고 조정합니다. Amazon RDS for PostgreSQL은 다음 버전에서 `pgactive` 확장을 지원합니다.
+ RDS for PostgreSQL 17.0 이상의 모든 버전
+ RDS for PostgreSQL 16.1 이상의 16 버전
+ RDS for PostgreSQL 15.4-R2 이상의 15 버전
+ RDS for PostgreSQL 14.10 이상의 14 버전
+ RDS for PostgreSQL 13.13 이상의 13 버전
+ RDS for PostgreSQL 12.17 이상의 12 버전
+ RDS for PostgreSQL 11.22

**참고**  
복제 구성에서 둘 이상의 데이터베이스에 쓰기 작업이 있는 경우 충돌이 발생할 수 있습니다. 자세한 내용은 [액티브-액티브 복제의 충돌 처리](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md) 섹션을 참조하세요.

**Topics**
+ [pgactive 확장에 대한 제한 사항](#Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations)
+ [pgactive 확장 기능 초기화](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md)
+ [RDS for PostgreSQL DB 인스턴스용 액티브-액티브 복제 설정](Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication.md)
+ [pgactive 멤버 간의 복제 지연 측정](Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag.md)
+ [pgactive 확장에 대한 파라미터 설정 구성](Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.md)
+ [액티브-액티브 충돌 이해](Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication.md)
+ [pgactive 스키마 이해](Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.md)
+ [pgactive 함수 참조](pgactive-functions-reference.md)
+ [액티브-액티브 복제의 충돌 처리](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md)
+ [액티브-액티브 복제의 시퀀스 처리](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md)

## pgactive 확장에 대한 제한 사항
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations"></a>
+ 모든 테이블에는 프라이머리 키가 필요합니다. 없는 경우 업데이트 및 삭제가 허용되지 않습니다. 프라이머리 키 열의 값은 업데이트해서는 안 됩니다.
+ 시퀀스는 간격이 있을 수 있으며 경우에 따라 순서를 따르지 않을 수도 있습니다. 시퀀스는 복제되지 않습니다. 자세한 내용은 [액티브-액티브 복제의 시퀀스 처리](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md) 섹션을 참조하세요.
+ DDL 및 대형 객체는 복제되지 않습니다.
+ 보조 고유 인덱스로 인해 데이터 차이가 발생할 수 있습니다.
+ 그룹 내 모든 노드에서 데이터 정렬이 동일해야 합니다.
+ 노드 간 로드 밸런싱은 안티 패턴입니다.
+ 대규모 트랜잭션으로 인해 복제 지연이 발생할 수 있습니다.

# pgactive 확장 기능 초기화
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup"></a>

RDS for PostgreSQL DB 인스턴스에서 `pgactive` 확장 기능을 초기화하려면 `rds.enable_pgactive` 파라미터 값을 `1`로 설정한 다음 데이터베이스에 확장을 생성합니다. 이렇게 하면 파라미터 `rds.logical_replication` 및 `track_commit_timestamp`가 자동으로 활성화되고 `wal_level` 값이 `logical`로 설정됩니다.

이러한 작업을 수행하려면 `rds_superuser` 역할의 권한이 있어야 합니다.

AWS Management Console 또는 AWS CLI를 사용하여 PostgreSQL DB 인스턴스에 필요한 RDS를 생성할 수 있습니다. 다음 단계에서는 RDS for PostgreSQL DB 인스턴스가 사용자 지정 DB 파라미터 그룹에 연결되어 있다고 가정합니다. 사용자 지정 DB 파라미터 그룹 생성에 대한 자세한 내용은 [Amazon RDS의 파라미터 그룹](USER_WorkingWithParamGroups.md) 단원을 참조하세요.

## 콘솔
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CON"></a>

**pgactive 확장 기능을 초기화하려면**

1. AWS Management Console에 로그인한 후 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)에서 Amazon RDS 콘솔을 엽니다.

1. 탐색 창에서 RDS for PostgreSQL DB 인스턴스를 선택합니다.

1. RDS for PostgreSQL DB 인스턴스의 **구성** 탭을 엽니다. 인스턴스 세부 정보에서 **DB 인스턴스 파라미터 그룹** 링크를 찾습니다.

1. 링크를 선택하여 RDS for PostgreSQL DB 인스턴스와 연결된 사용자 지정 파라미터를 엽니다.

1. `rds.enable_pgactive` 파라미터를 찾아 `1`로 설정하여 `pgactive` 기능을 초기화합니다.

1. **변경 사항 저장**을 선택합니다.

1. Amazon RDS 콘솔의 탐색 창에서 **데이터베이스**를 선택합니다.

1. RDS for PostgreSQL DB 인스턴스를 선택한 다음 **작업** 메뉴에서 **재부팅**을 선택합니다.

1. DB 인스턴스 재부팅을 확인하여 변경 사항을 적용합니다.

1. DB 인스턴스를 사용할 수 있게 되면 `psql` 또는 다른 PostgreSQL 클라이언트를 사용하여 RDS for PostgreSQL DB 인스턴스에 연결합니다.

   다음 예시에서는 RDS for PostgreSQL DB 인스턴스에 *postgres*라는 기본 데이터베이스가 있다고 가정합니다.

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

1. pgactive가 초기화되었는지 확인하려면 다음 명령을 실행합니다.

   ```
   postgres=>SELECT setting ~ 'pgactive' 
   FROM pg_catalog.pg_settings
   WHERE name = 'shared_preload_libraries';
   ```

   `pgactive`가 `shared_preload_libraries`에 들어 있는 경우 앞의 명령은 다음을 반환합니다.

   ```
   ?column? 
   ----------
    t
   ```

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CLI"></a>

**pgactive 확장 기능을 초기화하려면**

AWS CLI를 사용하여 `pgactive`를 초기화하려면 다음 절차와 같이 [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) 작업을 호출하여 사용자 지정 파라미터 그룹의 특정 파라미터를 수정합니다.

1. 다음 AWS CLI 명령으로 `rds.enable_pgactive`를 `1`로 설정하여 RDS for PostgreSQL DB 인스턴스의 `pgactive` 기능을 초기화합니다.

   ```
   postgres=>aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=rds.enable_pgactive,ParameterValue=1,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. 다음 AWS CLI 명령으로 RDS for PostgreSQL DB 인스턴스를 재부팅하여 `pgactive` 라이브러리가 초기화되도록 합니다.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. 인스턴스를 사용할 수 있다면 `psql`을 사용하여 RDS for PostgreSQL DB 인스턴스에 연결합니다.

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

1. pgactive가 초기화되었는지 확인하려면 다음 명령을 실행합니다.

   ```
   postgres=>SELECT setting ~ 'pgactive' 
   FROM pg_catalog.pg_settings
   WHERE name = 'shared_preload_libraries';
   ```

   `pgactive`가 `shared_preload_libraries`에 들어 있는 경우 앞의 명령은 다음을 반환합니다.

   ```
   ?column? 
   ----------
    t
   ```

# 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;
   ```

# pgactive 멤버 간의 복제 지연 측정
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag"></a>

다음 쿼리를 사용하여 `pgactive` 멤버 간의 복제 지연을 볼 수 있습니다. 모든 `pgactive` 노드에서 이 쿼리를 실행하면 전체 상황을 파악할 수 있습니다.

```
    
app=> SELECT * FROM pgactive.pgactive_get_replication_lag_info();
│-[ RECORD 1 ]--------+---------------------------------------------
│node_name            | node2-app
│node_sysid           | 7481018224801653637
│application_name     | pgactive:7481018224801653637:send
│slot_name            | pgactive_16385_7481018224801653637_0_16385__
│active               | t
│active_pid           | 783486
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/2108150
│confirmed_flush_lsn  | 0/2154690
│sent_lsn             | 0/2154690
│write_lsn            | 0/2154690
│flush_lsn            | 0/2154690
│replay_lsn           | 0/2154690
│-[ RECORD 2 ]--------+---------------------------------------------
│node_name            | node1-app
│node_sysid           | 7481018033434600853
│application_name     | pgactive:7481018033434600853:send
│slot_name            | pgactive_16385_7481018033434600853_0_16385__
│active               | t
│active_pid           | 783488
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/20F5AD0
│confirmed_flush_lsn  | 0/214EF68
│sent_lsn             | 0/214EF68
│write_lsn            | 0/214EF68
│flush_lsn            | 0/214EF68
│replay_lsn           | 0/214EF68
```

최소한 다음 진단을 모니터링합니다.

활성화  
활성이 false이면 알림을 설정합니다. 이는 슬롯이 현재 사용 중이 아님을 나타냅니다(구독자 인스턴스가 게시자와 연결 해제됨).

pending\$1wal\$1decoding  
PostgreSQL의 논리적 복제에서 WAL 파일은 이진 형식으로 저장됩니다. 게시자는 이러한 WAL 변경 사항을 디코딩하고 논리적 변경(예: 삽입, 업데이트 또는 삭제 작업)으로 변환해야 합니다.  
지표 pending\$1wal\$1decoding은 게시자 측에서 디코딩 대기 중인 WAL 파일 수를 보여 줍니다.  
이 수는 다음과 같은 요인으로 인해 증가할 수 있습니다.  
+ 구독자가 연결되지 않은 경우 활성 상태는 false이고 pending\$1wal\$1decoding은 증가합니다.
+ 슬롯이 활성 상태이지만 게시자가 WAL 변경 볼륨을 따라갈 수 없습니다.

pending\$1wal\$1to\$1apply  
지표 pending\$1wal\$1apply는 구독자 측에서 적용 대기 중인 WAL 파일 수를 나타냅니다.  
몇 가지 요인으로 인해 구독자가 변경 사항을 적용하지 못하고 다음과 같은 디스크 전체 시나리오가 발생할 수 있습니다.  
+ 스키마 차이 - 예를 들어 샘플이라는 테이블의 WAL 스트림이 변경되었지만 해당 테이블이 구독자 측에 없는 경우
+ 프라이머리 키 열의 값이 업데이트됨
+ 보조 고유 인덱스로 인해 데이터 분산이 발생할 수 있음

# pgactive 확장에 대한 파라미터 설정 구성
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters"></a>

다음 쿼리를 사용하여 `pgactive` 확장과 관련된 모든 파라미터를 볼 수 있습니다.

```
app=> SELECT * FROM pg_settings WHERE name LIKE 'pgactive.%';
```

다양한 파라미터를 사용하여 `pgactive` 확장을 구성할 수 있습니다. 이러한 파라미터는 AWS Management Console 또는 AWS CLI 인터페이스를 통해 설정할 수 있습니다.

## 기본 pgactive 확장 파라미터
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.mainparams"></a>

다음 표에서는 `pgactive` 확장의 기본 파라미터에 대한 참조를 제공합니다.


| 파라미터 | 단위 | 기본값 | 설명 | 
| --- | --- | --- | --- | 
| pgactive.conflict\$1logging\$1include\$1tuples | `boolean` | –  | `pgactive` 확장에 대한 전체 튜플 정보를 로깅합니다.  변경 사항을 적용하려면 서버를 재시작해야 합니다.  | 
| pgactive.log\$1conflicts\$1to\$1table | `boolean` | –  | `pgactive` 확장이 감지된 충돌을 `pgactive.pgactive_conflict_history` 테이블에 로깅할지 여부를 결정합니다. 자세한 내용은 충돌 로깅을 참조하세요.  변경 사항을 적용하려면 서버를 재시작해야 합니다.  | 
| pgactive.log\$1conflicts\$1to\$1logfile | `boolean` | –  | `pgactive` 확장이 감지된 충돌을 PostgreSQL 로그 파일에 로깅할지 여부를 결정합니다. 자세한 내용은 충돌 로깅을 참조하세요.  변경 사항을 적용하려면 서버를 재시작해야 합니다.  | 
| pgactive.synchronous\$1commit | `boolean` | 끄기 | pgactive 적용 작업자의 커밋 동작을 결정합니다. 비활성화(꺼짐)되면 적용 작업자가 비동기 커밋을 수행하여 적용 작업 중에 PostgreSQL 처리량이 개선되지만, 업스트림에 대한 재생 확인은 지연됩니다. `off`로 설정하면 항상 안전하고 트랜잭션 손실이나 건너뛰기가 발생하지 않습니다. 이 설정은 다운스트림 노드의 디스크 플러시 타이밍 및 확인이 업스트림으로 전송되는 시점에만 영향을 미칩니다. 체크포인트 또는 주기적 작업과 같은 관련 없는 작업을 통해 커밋이 디스크로 플러시될 때까지 시스템에서 재생 플러시 확인 전송이 지연됩니다. 그러나 업스트림이 `synchronous_standby_names`에 나열된 다운스트림을 포함하는 경우 이를 `off`로 설정하면 업스트림에서 동기 커밋이 클라이언트에 성공을 보고하는 데 더 오랜 시간이 걸립니다. 이 경우 파라미터를 `on`으로 설정하세요.  `synchronous_standby_names`에 나열된 노드를 사용하여 이 파라미터를 `on`으로 설정하더라도 액티브-액티브 구성에서 복제 충돌이 발생할 수 있습니다. 이는 시스템에 노드 간 잠금 및 글로벌 스냅샷 관리가 부족하여 서로 다른 노드의 동시 트랜잭션이 동일한 튜플을 수정할 수 있기 때문입니다. 또한 트랜잭션은 업스트림 노드에서 커밋한 후에만 복제를 시작합니다. 동기 커밋을 활성화해도 pgactive 확장이 항상 일관된 시스템으로 변환되지 않습니다.  | 
| pgactive.temp\$1dump\$1directory | `string` | – | 초기 설정 중 데이터베이스 복제 작업에 필요한 임시 스토리지 경로를 정의합니다. 이 디렉터리는 postgres 사용자가 쓸 수 있어야 하며 전체 데이터베이스 덤프를 포함할 만큼 충분한 스토리지 공간이 있어야 합니다. 시스템은 논리적 복사 작업이 포함된 초기 데이터베이스 설정 중에만 이 위치를 사용합니다. 이 파라미터는 `pgactive_init_copy command`에서 사용되지 않습니다. | 
| pgactive.max\$1ddl\$1lock\$1delay | `milliseconds` | `-1` | 동시 쓰기 트랜잭션을 강제로 중단하기 전에 DDL 잠금의 최대 대기 시간을 지정합니다. 기본값은 `-1`이며, 이는 `max_standby_streaming_delay`에 설정된 값을 채택합니다. 이 파라미터는 시간 단위를 허용합니다. 예를 들어 10초를 나타내는 10s로 설정할 수 있습니다. 이 대기 기간 동안 시스템은 지속적 쓰기 트랜잭션이 커밋되거나 롤백될 때까지 기다리는 동안 DDL 잠금 획득을 시도합니다. 자세한 내용은 DDL 잠금을 참조하세요. | 
| pgactive.ddl\$1lock\$1timeout | `milliseconds` | `-1` | DDL 잠금 시도가 잠금을 얻기 위해 대기하는 시간을 지정합니다. 기본값은 lock\$1timeout에 지정된 값을 사용하는 `-1`입니다. 10초를 나타내는 10s와 같은 시간 단위를 사용하여 이 파라미터를 설정할 수 있습니다. 이 타이머는 DDL 잠금을 얻기 위한 대기 기간만 제어합니다. 시스템이 잠금을 얻고 DDL 작업을 시작하면 타이머가 중지됩니다. 이 파라미터는 DDL 잠금을 유지할 수 있는 총 기간 또는 전체 DDL 작업 시간을 제한하지 않습니다. 작업의 총기간을 제어하려면 `statement_timeout`을 대신 사용합니다. 자세한 내용은 DDL 잠금을 참조하세요. | 
| pgactive.debug\$1trace\$1ddl\$1locks\$1level | `boolean` | –  | `pgactive` 확장의 DDL 잠금 작업에 대한 기본 디버그 로그 수준을 재정의합니다. 이 설정을 구성하면 기본 수준 대신 LOG 디버그 수준에서 DDL 잠금 관련 메시지가 내보내집니다. 전체 서버에서 상세 `DEBUG1` 또는 `DEBUG2` 로그 수준을 활성화하지 않고 DDL 잠금 활동을 모니터링하려면 이 파라미터를 사용합니다. 사용 가능한 로그 수준(상세 수준이 낮은 순): [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 모니터링 옵션에 대한 자세한 내용은 글로벌 DDL 잠금 모니터링을 참조하세요.  이 설정에 대한 변경 사항은 구성을 다시 로드할 때 적용됩니다. 서버를 다시 시작할 필요가 없습니다.   | 

## 추가 pgactive 확장 파라미터
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.addparams"></a>

다음 표에는 `pgactive` 확장에 사용할 수 있는 덜 자주 사용되는 구성 옵션과 내부 구성 옵션이 나와 있습니다.


| 파라미터 | 단위 | 기본값 | 설명 | 
| --- | --- | --- | --- | 
| pgactive.debug\$1apply\$1delay | `integer` | – |  `pgactive.pgactive_connections` 항목에 명시적 적용 지연이 없는 구성된 연결에 적용 지연(밀리초)을 설정합니다. 이 지연은 노드 만들기 또는 조인 시간 중에 설정되며, pgactive는 커밋된 이후 지정된 밀리초 이상이 경과할 때까지 피어 노드에서 트랜잭션을 재생하지 않습니다. 주로 테스트 환경에서 지연 시간이 긴 네트워크를 시뮬레이션하여 충돌을 더 쉽게 발생시키는 데 사용됩니다. 예를 들어 노드 A와 B의 지연 시간이 500ms인 경우 노드 A에 값을 삽입한 후 노드 B에 충돌하는 삽입을 수행할 수 있는 시간이 500ms 이상입니다.  서버를 다시 로드하거나 적용 작업자를 다시 시작해야 적용됩니다.  | 
| pgactive.connectability\$1check\$1duration | `integer` | –  | 실패한 시도 중에 데이터베이스 작업자가 연결을 설정하려고 시도하는 기간(초)을 지정합니다. 작업자는 성공하거나 이 제한 시간 값에 도달할 때까지 초당 1회 연결을 시도합니다. 이 설정은 작업자가 연결을 설정할 준비가 되기 전에 데이터베이스 엔진이 시작될 때 유용합니다. | 
| pgactive.skip\$1ddl\$1replication | `boolean` | `on` | `pgactive`가 활성화된 Amazon RDS에서 DDL 변경 사항이 복제되거나 처리되는 방식을 제어합니다. `on`으로 설정하면 노드가 비 pgcctive 노드와 같은 DDL 변경 사항을 처리합니다. 이 파라미터를 사용할 때는 다음 요구 사항이 적용됩니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 최고 사용자 권한을 사용하여 글로벌, 로컬(세션 수준)의 두 가지 방법으로 이 파라미터를 수정할 수 있습니다.  이 파라미터를 잘못 변경하면 복제 설정이 손상될 수 있습니다.  | 
| pgactive.do\$1not\$1replicate | `boolean` | – | 이 파라미터는 내부 전용입니다. 트랜잭션에서 이 파라미터를 설정하면 변경 사항이 DB 클러스터의 다른 노드에 복제되지 않습니다.  이 파라미터를 잘못 변경하면 복제 설정이 손상될 수 있습니다.  | 
| pgactive.discard\$1mismatched\$1row\$1attributes | `boolean` | –  | 이 파라미터는 전문가 전용입니다. 특정 복제 문제를 해결할 때만 이 파라미터를 사용하는 것이 좋습니다. 다음과 같은 경우 이 파라미터를 사용합니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 이 설정은 다음 오류 메시지를 재정의하고 데이터 분산이 발생하여 복제가 계속되도록 합니다. `cannot right-pad mismatched attributes; attno %u is missing in local table and remote row has non-null, non-dropped value for this attribute`   이 파라미터를 잘못 변경하면 복제 설정이 손상될 수 있습니다.   | 
| pgactive.debug\$1trace\$1replay | `boolean` | – | `on`으로 설정하면 다운스트림 적용 작업자가 처리하는 각 원격 작업에 대해 로그 메시지를 내보냅니다. 로그에는 다음이 포함됩니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 로그는 대기 중인 DDL 명령과 테이블 삭제도 캡처합니다.para> 기본적으로 로그에는 행 필드 콘텐츠가 포함되지 않습니다. 로그에 행 값을 포함하려면 다음 플래그가 활성화된 상태로 다시 컴파일해야 합니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html)  이 로깅 설정을 활성화하면 성능에 영향이 미칠 수 있습니다. 문제 해결을 위해 필요한 경우에만 활성화하는 것이 좋습니다. 이 설정에 대한 변경 사항은 구성을 다시 로드할 때 적용됩니다. 서버를 다시 시작할 필요가 없습니다.   | 
| pgactive.extra\$1apply\$1connection\$1options |  | – | pgactive 노드와의 모든 피어 노드 연결에 대해 연결 파라미터를 구성할 수 있습니다. 이러한 파라미터는 keepalive 및 SSL 모드와 같은 설정을 제어합니다. 기본적으로 pgactive는 다음 연결 파라미터를 사용합니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 기본 파라미터를 재정의하려면 다음과 유사한 명령을 사용합니다. pgactive.extra\$1apply\$1connection\$1options = 'keepalives=0' 개별 노드 연결 문자열은 이러한 설정과 pgactive의 기본 제공 연결 옵션보다 우선합니다. 연결 문자열 형식에 대한 자세한 내용은 [libpq connection strings](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING)를 참조하세요. 기본 keepalive 설정을 활성화된 상태로 유지하는 것이 좋습니다. 신뢰할 수 없는 네트워크를 통해 대규모 트랜잭션을 완료하는 데 문제가 있는 경우에만 keepalive를 비활성화합니다.  기본 keepalive 설정을 활성화된 상태로 유지하는 것이 좋습니다. 신뢰할 수 없는 네트워크를 통해 대규모 트랜잭션을 완료하는 데 문제가 있는 경우에만 keepalive를 비활성화합니다. 이 설정에 대한 변경 사항은 구성을 다시 로드할 때 적용됩니다. 서버를 다시 시작할 필요가 없습니다.  | 
| pgactive.init\$1node\$1parallel\$1jobs (int) |  | – | 논리적 노드가 `pgactive.pgactive_join_group` 함수와 조인하는 동안 `pg_dump` 및 `pg_restore`가 사용할 수 있는 병렬 작업 수를 지정합니다. 이 설정에 대한 변경 사항은 구성을 다시 로드할 때 적용됩니다. 서버를 다시 시작할 필요가 없습니다. | 
| pgactive.max\$1nodes | `int` | 4 |  pgactive 확장 그룹에 허용되는 최대 노드 수를 지정합니다. 기본값은 노드 4개입니다. 이 파라미터의 값을 설정할 때 다음 사항을 고려해야 합니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) 이 파라미터는 구성 파일에서 `ALTER SYSTEM SET` 명령을 사용하여 두 가지 방법으로 설정할 수 있습니다. 이 파라미터의 기본값은 `4`입니다. 즉, 어느 시점에든 `pgactive` 확장 그룹에 최대 4개의 노드가 허용됩니다.  변경 사항은 서버를 다시 시작한 후에 적용됩니다.  | 
| pgactive.permit\$1node\$1identifier\$1getter\$1function\$1creation | `boolean` | – | 이 파라미터는 내부 전용입니다. 활성화하면 `pgactive` 확장을 통해 pgactive 노드 식별자 getter 함수를 만들 수 있습니다. | 

# 액티브-액티브 충돌 이해
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication"></a>

액티브-액티브 모드에서 pgactive를 사용하는 경우 여러 노드에서 동일한 테이블에 쓰면 데이터 충돌이 발생할 수 있습니다. 일부 클러스터링 시스템은 분산 잠금을 사용하여 동시 액세스를 방지하지만 pgactive는 지리적으로 분산된 애플리케이션에 더 적합한 낙관적 접근 방식을 취합니다.

일부 데이터베이스 클러스터링 시스템은 분산 잠금을 사용하여 동시 데이터 액세스를 방지합니다. 이 접근 방식은 서버가 가까이에 있을 때 작동하지만 우수한 성능을 위해 매우 짧은 지연 시간을 요구하기 때문에 지리적으로 분산된 애플리케이션을 지원하지 않습니다. pgactive 확장은 분산 잠금(비관적 접근 방식)을 사용하는 대신 낙관적 접근 방식을 사용합니다. 이는 다음을 의미합니다.
+ 가능하면 충돌을 방지하는 데 도움이 됩니다.
+ 특정 유형의 충돌이 발생하도록 허용합니다.
+ 충돌이 발생할 때 충돌을 해결합니다.

이 접근 방식은 분산 애플리케이션을 구축할 때 더 많은 유연성을 제공합니다.

## 충돌이 발생하는 방법
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.howconflicts"></a>

노드 간 충돌은 관련된 모든 트랜잭션이 동일한 노드에서 동시에 발생한 경우 발생할 수 없는 이벤트 시퀀스에서 발생합니다. 노드는 트랜잭션 커밋 후에만 변경 사항을 교환하기 때문에 각 트랜잭션은 커밋된 노드에서 개별적으로 유효하지만 그동안 다른 작업을 수행한 다른 노드에서 실행되는 경우에는 유효하지 않습니다. pgactive 적용은 기본적으로 다른 노드에서 트랜잭션을 재생하므로 적용 중인 트랜잭션과 수신 노드에서 커밋된 트랜잭션 간에 충돌이 있는 경우 재생 작업이 실패할 수 있습니다.

 모든 트랜잭션이 단일 노드에서 실행될 때 대부분의 충돌이 발생할 수 없는 이유는 PostgreSQL에 이를 방지하기 위한 다음과 같은 트랜잭션 간 통신 메커니즘이 있기 때문입니다.
+ UNIQUE 인덱스
+ SEQUENCE
+ 행 및 관계 잠금
+ SERIALIZABLE 종속성 추적

이러한 모든 메커니즘은 원치 않는 동시성 문제를 방지하기 위해 트랜잭션 간에 통신하는 방법입니다.

pgactive는 분산 트랜잭션 관리자 또는 잠금 관리자를 사용하지 않으므로 지연 시간을 줄이고 네트워크 파티션을 잘 처리합니다. 그러나 이는 서로 다른 노드의 트랜잭션이 서로 완전히 격리되어 실행됨을 의미합니다. 격리는 일반적으로 데이터베이스 일관성을 개선하지만 이 경우 충돌을 방지하려면 격리를 줄여야 합니다.

## 충돌 유형
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes"></a>

발생할 수 있는 충돌은 다음과 같습니다.

**Topics**
+ [PRIMARY KEY 또는 UNIQUE 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1)
+ [INSERT/INSERT 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2)
+ [여러 UNIQUE 제약 조건을 위반하는 INSERT](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3)
+ [UPDATE/UPDATE 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4)
+ [PRIMARY KEY의 UPDATE 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5)
+ [여러 UNIQUE 제약 조건을 위반하는 UPDATE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6)
+ [UPDATE/DELETE 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7)
+ [INSERT/UPDATE 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8)
+ [DELETE/DELETE 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9)
+ [외래 키 제약 조건 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10)
+ [제외 제약 조건 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11)
+ [글로벌 데이터 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12)
+ [잠금 충돌 및 교착 상태 중단](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13)
+ [분산 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14)

### PRIMARY KEY 또는 UNIQUE 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1"></a>

행 충돌은 여러 작업이 단일 노드에서 불가능한 방식으로 동일한 행 키를 수정하려고 할 때 발생합니다. 이러한 충돌은 가장 일반적인 유형의 데이터 충돌을 나타냅니다.

pgactive는 마지막 업데이트 우선 처리 또는 사용자 지정 충돌 핸들러를 통해 감지된 충돌을 해결합니다.

행 충돌에는 다음이 포함됩니다.
+ INSERT 및 INSERT
+ INSERT 및 UPDATE
+ UPDATE 및 DELETE
+ INSERT 및 DELETE
+ DELETE 및 DELETE
+ INSERT 및 DELETE

### INSERT/INSERT 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2"></a>

이 가장 일반적인 충돌은 서로 다른 두 노드의 INSERT가 동일한 PRIMARY KEY 값(또는 PRIMARY KEY가 없는 경우 동일한 UNIQUE 제약 조건 값)으로 튜플을 만들 때 발생합니다.

pgactivelink는 최신 튜플을 유지하기 위해 원본 호스트의 타임스탬프를 사용하여 INSERT 충돌을 해결합니다. 사용자 지정 충돌 핸들러를 사용하여 이 기본 동작을 재정의할 수 있습니다. 이 프로세스에는 특별한 관리자 작업이 필요하지 않지만 pgactivelink는 모든 노드에서 INSERT 작업 중 하나를 삭제합니다. 사용자 지정 핸들러가 구현하지 않는 한 자동 데이터 병합이 수행되지 않습니다.

pgactivelink는 단일 제약 조건 위반과 관련된 충돌만 해결할 수 있습니다. INSERT가 여러 UNIQUE 제약 조건을 위반하는 경우 추가 충돌 해결 전략을 구현해야 합니다.

### 여러 UNIQUE 제약 조건을 위반하는 INSERT
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3"></a>

INSERT/INSERT 충돌은 PRIMARY KEY를 포함하여 여러 UNIQUE 제약 조건을 위반할 수 있습니다. pgactivelink는 단일 UNIQUE 제약 조건과 관련된 충돌만 처리할 수 있습니다. 충돌이 여러 UNIQUE 제약 조건을 위반하면 적용 작업자가 실패하고 다음 오류를 반환합니다.

`multiple unique constraints violated by remotely INSERTed tuple.`

이전 버전에서는 이 상황으로 인해 '분산된 고유성 충돌' 오류가 대신 발생했습니다.

이러한 충돌을 해결하려면 수동 조치를 취해야 합니다. 충돌하는 로컬 튜플을 DELETE하거나 UPDATE하여 새 원격 튜플과의 충돌을 제거합니다. 여러 충돌하는 튜플을 해결해야 할 수 있습니다. 현재 pgactivelink는 여러 고유 제약 조건을 위반하는 튜플을 무시, 삭제 또는 병합하는 기능을 기본적으로 제공하지 않습니다.

**참고**  
자세한 내용은 여러 UNIQUE 제약 조건을 위반하는 UPDATE를 참조하세요.

### UPDATE/UPDATE 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4"></a>

이 충돌은 PRIMARY KEY를 변경하지 않고 두 노드가 동시에 동일한 튜플을 수정할 때 발생합니다. pgactivelink는 마지막 업데이트 우선 로직 또는 사용자 지정 충돌 핸들러(정의된 경우)를 사용하여 이러한 충돌을 해결합니다. PRIMARY KEY는 튜플 매칭 및 충돌 해결에 필수적입니다. PRIMARY KEY가 없는 테이블의 경우 pgactivelink는 다음 오류와 함께 UPDATE 작업을 거부합니다.

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

### PRIMARY KEY의 UPDATE 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5"></a>

pgactive에는 PRIMARY KEY 업데이트를 처리할 때 제한 사항이 있습니다. PRIMARY KEY에서 UPDATE 작업을 수행할 수 있지만 pgactive는 이러한 작업에 대해 마지막 업데이트 우선 로직을 사용하여 충돌을 자동으로 해결할 수 없습니다. PRIMARY KEY 업데이트가 기존 값과 충돌하지 않도록 해야 합니다. PRIMARY KEY 업데이트 중에 충돌이 발생하면 수동 개입이 필요한 분산 충돌이 됩니다. 이러한 상황 처리에 대한 자세한 내용은 [분산 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14) 섹션을 참조하세요.

### 여러 UNIQUE 제약 조건을 위반하는 UPDATE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6"></a>

수신 UPDATE가 여러 UNIQUE 제약 조건 또는 PRIMARY KEY 값을 위반하는 경우 pgactivelink는 마지막 업데이트 우선 충돌 해결을 적용할 수 없습니다. 이 동작은 여러 제약 조건 위반이 있는 INSERT 작업과 유사합니다. 이러한 상황에서는 수동 개입이 필요한 분산 충돌이 발생합니다. 자세한 내용은 [분산 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14) 섹션을 참조하세요.

### UPDATE/DELETE 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7"></a>

이 충돌은 한 노드가 행을 UPDATE하는 동시에 다른 노드가 해당 행을 DELETE할 때 발생합니다. 이 경우 재생 시 UPDATE/DELETE 충돌이 발생합니다. 해결 방법은 사용자 지정 충돌 핸들러에서 달리 지정하지 않는 한 DELETE 이후에 도착하는 모든 UPDATE를 삭제하는 것입니다.

pgactivelink는 튜플을 매칭하고 충돌을 해결하기 위해 PRIMARY KEY가 필요합니다. PRIMARY KEY가 없는 테이블의 경우 다음 오류와 함께 DELETE 작업을 거부합니다.

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

**참고**  
pgactivelink는 UPDATE/DELETE와 INSERT/UPDATE 충돌을 구분할 수 없습니다. 두 경우 모두 UPDATE는 존재하지 않는 행에 영향을 미칩니다. 비동기식 복제와 노드 간 재생 순서의 부재로 인해 pgactivelink는 UPDATE가 새 행(INSERT가 아직 수신되지 않음)인지 아니면 삭제된 행인지 확인할 수 없습니다. 두 시나리오 모두에서 pgactivelink는 UPDATE를 삭제합니다.

### INSERT/UPDATE 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8"></a>

이 충돌은 다중 노드 환경에서 발생할 수 있습니다. 이는 한 노드가 행을 INSERT, 두 번째 노드를 UPDATE하고, 세 번째 노드가 원래 INSERT보다 먼저 UPDATE를 수신할 때 발생합니다. 사용자 지정 충돌 트리거에서 달리 지정하지 않는 한 기본적으로 pgactivelink는 UPDATE를 삭제하여 이러한 충돌을 해결합니다. 이 해결 방법을 사용하면 노드 간에 데이터 불일치가 발생할 수 있습니다. 유사한 시나리오 및 처리에 대한 자세한 내용은 [UPDATE/DELETE 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7) 섹션을 참조하세요.

### DELETE/DELETE 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9"></a>

이 충돌은 서로 다른 두 노드가 동시에 동일한 튜플을 삭제할 때 발생합니다. pgactivelink는 두 DELETE 작업의 최종 결과가 동일하기 때문에 이러한 충돌을 무해하게 간주합니다. 이 시나리오에서 pgactivelink는 데이터 일관성에 영향을 주지 않고 DELETE 작업 중 하나를 무시합니다.

### 외래 키 제약 조건 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10"></a>

FOREIGN KEY 제약 조건은 기존 로컬 데이터에 원격 트랜잭션을 적용할 때 충돌을 일으킬 수 있습니다. 이러한 충돌은 일반적으로 트랜잭션이 원본 노드의 논리적 순서와 다른 순서로 적용될 때 발생합니다.

기본적으로 pgactive는 session\$1replication\$1role이 `replica`인 상태로 변경 사항을 적용하여 복제 중에 외래 키 검사를 우회합니다. 액티브-액티브 구성에서는 외래 키 위반이 발생할 수 있습니다. 대부분의 위반은 일시적이며 복제가 동기화되면 해결됩니다. 그러나 pgactive는 노드 간 행 잠금을 지원하지 않기 때문에 참조 대상이 없는 외래 키가 발생할 수 있습니다.

이 동작은 파티션 내성 비동기식 액티브-액티브 시스템에 고유합니다. 예를 들어 노드 A는 새 하위 행을 삽입하는 반면 노드 B는 상위 행을 동시에 삭제합니다. 시스템은 노드 간에 이러한 유형의 동시 수정을 방지할 수 없습니다.

외래 키 충돌을 최소화하려면 다음을 수행하는 것이 좋습니다.
+ 외래 키 관계를 밀접하게 관련된 엔터티로 제한합니다.
+ 가능하면 단일 노드에서 관련 엔터티를 수정합니다.
+ 수정이 거의 필요하지 않은 개체를 선택합니다.
+ 수정을 위한 애플리케이션 수준 동시성 제어를 구현합니다.

### 제외 제약 조건 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11"></a>

 pgactive 링크는 제외 제약 조건을 지원하지 않으며 이러한 조건이 만들어지지 못하게 합니다.

**참고**  
기존 독립 실행형 데이터베이스를 pgactivelink 데이터베이스로 변환하는 경우 모든 제외 제약 조건을 수동으로 삭제합니다.

분산 비동기 시스템에서는 제약 조건을 위반하는 행 집합이 없음을 보장할 수 없습니다. 이는 서로 다른 노드의 모든 트랜잭션이 완전히 격리되기 때문입니다. 제외 제약 조건으로 인해 노드에서 다른 노드로 재생을 진행할 수 없는 재생 교착 상태가 발생할 수 있습니다.

pgactive Link가 제외 제약 조건을 만들도록 강제하거나 독립 실행형 데이터베이스를 pgactive Link로 변환할 때 기존 제외 제약 조건을 삭제하지 않으면 복제가 중단될 수 있습니다. 복제 진행 상황을 복원하려면 원격 트랜잭션을 적용할 수 있도록 수신되는 원격 튜플과 충돌하는 로컬 튜플을 제거하거나 변경합니다.

### 글로벌 데이터 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12"></a>

pgactivelink를 사용하는 경우 노드에 역할과 같은 서로 다른 글로벌 PostgreSQL 시스템 전체 데이터가 있을 때 충돌이 발생할 수 있습니다. 이러한 충돌로 인해 주로 DDL과 같은 작업이 성공하고 한 노드에서 커밋되지만 다른 노드에는 적용되지 않을 수 있습니다.

사용자가 한 노드에 있지만 다른 노드에는 없는 경우 다음 복제 문제가 발생할 수 있습니다.
+ Node1에는 이름이 `fred`인 사용자가 있지만 이 사용자는 Node2에 존재하지 않습니다.
+ `fred`가 Node1에서 테이블을 만들면 `fred`를 소유자로 사용하여 테이블이 복제됩니다.
+ 이 DDL 명령이 Node2에 적용되면 `fred` 사용자가 없기 때문에 실패합니다.
+ 이 실패는 Node2의 PostgreSQL 로그에서 ERROR를 생성하고 `pgactive.pgactive_stats.nr_rollbacks` 카운터를 증가시킵니다.

**해결 방법:** Node2에서 사용자 `fred`를 생성합니다. 사용자는 동일한 권한이 필요하지 않지만 두 노드 모두에 있어야 합니다.

한 노드에는 테이블이 있지만 다른 노드에는 없는 경우 데이터 수정 작업이 실패합니다.
+ Node1에는 Node2에 존재하지 않는 `foo`라는 테이블이 있습니다.
+ Node1의 `foo` 테이블에 대한 모든 DML 작업은 Node2에 복제되었을 때 실패합니다.

**해결 방법:** 동일한 구조로 Node2에 `foo` 테이블을 생성합니다.

**참고**  
pgactivelink는 현재 CREATE USER 명령 또는 DDL 작업을 복제하지 않습니다. DDL 복제는 향후 릴리스에 계획되어 있습니다.

### 잠금 충돌 및 교착 상태 중단
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13"></a>

pgactive 적용 프로세스는 일반 사용자 세션처럼 작동하므로 표준 행 및 테이블 잠금 규칙을 따릅니다. 이로 인해 pgactivelink 적용 프로세스가 사용자 트랜잭션 또는 다른 적용 프로세스가 보유한 잠금을 대기할 수 있습니다.

다음 유형의 잠금은 적용 프로세스에 영향을 미칠 수 있습니다.
+ 사용자 세션별 명시적 테이블 수준 잠금(LOCK TABLE ...)
+ 사용자 세션에 의한 명시적 행 수준 잠금(SELECT ... FOR UPDATE/FOR SHARE)
+ 외래 키로 인한 잠금
+ 로컬 활동이나 다른 서버의 적용으로 인해 발생하는 행의 UPDATE, INSERT, DELETE에 따른 암시적 잠금

다음 사이에 교착 상태가 발생할 수 있습니다.
+ pgactivelink 적용 프로세스 및 사용자 트랜잭션
+ 두 개의 적용 프로세스

교착 상태가 발생하면 PostgreSQL의 교착 상태 감지기는 문제 트랜잭션 중 하나를 종료합니다. pgactivelink 적용 작업자의 프로세스가 종료되면 자동으로 재시도되고 일반적으로 성공합니다.

**참고**  
이러한 문제는 일시적이며 일반적으로 관리자의 개입이 필요하지 않습니다. 유휴 사용자 세션의 잠금으로 인해 적용 프로세스가 장기간 차단된 경우 사용자 세션을 종료하여 복제를 재개할 수 있습니다. 이 상황은 사용자가 다른 사용자 세션에 영향을 미치는 긴 잠금을 유지하는 경우와 유사합니다.
잠금 관련 재생 지연을 식별하려면 PostgreSQL에서 `log_lock_waits` 기능을 활성화합니다.

### 분산 충돌
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14"></a>

노드 간에 동일해야 하는 데이터가 예기치 않게 다를 때 분산 충돌이 발생합니다. 이러한 충돌은 발생하지 않아야 하지만 현재 구현에서 모든 충돌을 안정적으로 방지할 수 있는 것은 아닙니다.

**참고**  
 모든 노드가 변경을 처리하기 전에 다른 노드가 동일한 행의 키를 변경할 경우 행의 PRIMARY KEY를 수정하면 분산 충돌이 발생할 수 있습니다. 프라이머리 키를 변경하지 않거나 지정된 노드 하나로 변경을 제한합니다. 자세한 내용은 [PRIMARY KEY의 UPDATE 충돌](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5) 섹션을 참조하세요.

행 데이터와 관련된 분산 충돌에는 일반적으로 관리자의 개입이 필요합니다. 이러한 충돌을 해결하려면 `pgactive.pgactive_do_not_replicate`를 사용하여 복제를 일시적으로 비활성화하면서 한 노드의 데이터를 다른 노드와 일치하도록 수동으로 조정해야 합니다. pgactive를 문서화된 대로 사용하고 안전하지 않은 것으로 표시된 설정이나 함수를 사용하지 않는 경우 이러한 충돌이 발생하지 않습니다.

 관리자는 이러한 충돌을 수동으로 해결해야 합니다. 충돌 유형에 따라와 `pgactive.pgactive_do_not_replicate` 같은 고급 옵션을 사용해야 합니다. 이러한 옵션을 잘못 사용하면 상황이 악화될 수 있으므로 주의해서 사용하세요. 가능한 충돌이 다양하기 때문에 범용 해결 지침을 제공할 수 없습니다.

서로 다른 노드에서 동일해야 하는 데이터가 예기치 않게 다를 때 분산 충돌이 발생합니다. 이러한 충돌은 발생하지 않아야 하지만 현재 구현에서 이러한 모든 충돌을 안정적으로 방지할 수 있는 것은 아닙니다.

## 충돌 방지 또는 허용
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.avoidconflicts"></a>

 대부분의 경우 적절한 애플리케이션 설계를 사용하여 충돌을 방지하거나 애플리케이션이 충돌을 허용하도록 할 수 있습니다.

 충돌은 여러 노드에서 동시 작업이 수행되는 경우에만 발생합니다. 충돌을 방지하려면:
+ 하나의 노드에만 쓰기
+ 각 노드의 독립 데이터베이스 하위 집합에 쓰기(예: 각 노드에 별도의 스키마 할당)

INSERT 및 INSERT 충돌의 경우 글로벌 시퀀스를 사용하여 충돌을 완전히 방지합니다.

 사용 사례에서 충돌이 허용되지 않는 경우 애플리케이션 수준에서 분산 잠금을 구현하는 것이 좋습니다. 가장 좋은 방법은 모든 충돌을 방지하려고 하지 않고 pgactive의 충돌 해결 메커니즘과 연계되도록 애플리케이션을 설계하는 것입니다. 자세한 내용은 [충돌 유형](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes) 섹션을 참조하세요.

## 충돌 로깅
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflictlogging"></a>

pgactivelink는 `pgactive.pgactive_conflict_history` 테이블에 충돌 인시던트를 로깅하여 액티브-액티브 충돌을 진단하고 처리하는 데 도움이 됩니다. 이 테이블에 대한 충돌 로깅은 `pgactive.log_conflicts_to_table`을 true로 설정한 경우에만 발생합니다. 또한 pgactive 확장은 `pgactive.log_conflicts_to_table` 설정에 관계없이 log\$1min\$1messages가 `LOG` 또는 `lower`로 설정된 경우 PostgreSQL 로그 파일에 충돌을 기록합니다.

 충돌 기록 테이블을 사용하여 다음을 수행할 수 있습니다.
+ 애플리케이션이 충돌을 생성하는 빈도 측정
+ 충돌이 발생하는 위치 식별
+ 애플리케이션을 개선하여 충돌률 감소
+ 충돌 해결로 원하는 결과가 나오지 않는 경우 감지
+ 사용자 정의 충돌 트리거 또는 애플리케이션 설계 변경이 필요한 위치 확인

 행 충돌의 경우 선택적으로 행 값을 로깅할 수 있습니다. 이는 `pgactive.log_conflicts_to_table` 설정에 의해 제어됩니다. 참고:
+ 이는 글로벌 데이터베이스 전체 옵션입니다.
+ 행 값 로깅에 대한 테이블별 제어는 없습니다.
+ 필드 번호, 배열 요소 또는 필드 길이에는 제한이 적용되지 않습니다.
+ 충돌을 트리거할 수 있는 수 메가바이트 크기의 행으로 작업하는 경우 이 기능을 활성화하지 않는 것이 좋습니다.

 충돌 기록 테이블에는 데이터베이스의 모든 테이블(각각 스키마가 다를 수 있음)의 데이터가 포함되어 있으므로 로깅된 행 값은 JSON 필드로 저장됩니다. JSON은 SQL에서 직접적으로 호출하는 것과 마찬가지로 `row_to_json`을 사용하여 만들어집니다. PostgreSQL은 `json_to_row` 함수를 제공하지 않으므로 로깅된 JSON에서 복합 형식 튜플을 재구성하려면 테이블별 코드(PL/pgSQL, PL/Python, PL/Perl 등)가 필요합니다.

**참고**  
사용자 정의 충돌에 대한 지원은 향후 확장 기능으로 계획되어 있습니다.

# pgactive 스키마 이해
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema"></a>

pgactive 스키마는 RDS for PostgreSQL에서 액티브-액티브 복제를 관리합니다. 이 스키마에는 복제 구성 및 상태 정보를 저장하는 테이블이 포함되어 있습니다.

**참고**  
pgactive 스키마는 발전 중이며 변경될 수 있습니다. 이러한 테이블의 데이터를 직접 수정하지 마세요.

pgactive 스키마의 키 테이블에는 다음이 포함됩니다.
+ `pgactive_nodes` - 액티브-액티브 복제 그룹의 노드에 대한 정보를 저장합니다.
+ `pgactive_connections` - 각 노드의 연결 세부 정보를 저장합니다.

## pgactive\$1nodes
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.nodes"></a>

pgactive\$1nodes는 액티브-액티브 복제 그룹에 참여하는 노드에 대한 정보를 저장합니다.


| 열 | Type | 콜레이션 | Nullable | 기본값 | 
| --- | --- | --- | --- | --- | 
| node\$1sysid | 텍스트 | – | Null이 아님 | – | 
| node\$1timeline | oid | – | Null이 아님 | – | 
| node\$1dboid | oid | – | Null이 아님 | – | 
| node\$1status | char | – | Null이 아님 | – | 
| node\$1name | 텍스트 | – | Null이 아님 | – | 
| node\$1dsn | 텍스트 | – | Null이 아님 | – | 
| node\$1init\$1from\$1dsn | 텍스트 | – | Null이 아님 | – | 
| node\$1read\$1only | 부울 | – | – | false | 
| node\$1seq\$1id | smallint | – | Null이 아님 | – | 

**node\$1sysid**  
`pgactive_create_group` 또는 `pgactive_join_group` 중에 생성된 노드의 고유 ID

**node\$1status**  
노드 준비 상태:  
+ **b** - 설정 시작
+ **i** - 초기화 중
+ **c** - 캐치업
+ **o** - 아웃바운드 슬롯을 만드는 중
+ **r** - 준비됨
+ **k** - 종료됨
이 열은 노드가 연결 또는 연결 해제되었는지 여부를 나타내지 않습니다.

**node\$1name**  
사용자가 제공한 고유 노드 이름입니다.

**node\$1dsn**  
연결 문자열 또는 사용자 매핑 이름입니다.

**node\$1init\$1from\$1dsn**  
이 노드가 생성된 DSN입니다.

## pgactive\$1connection
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.connection"></a>

pgactive\$1connections는 각 노드에 대한 연결 세부 정보를 저장합니다.


| 열 | Type | 콜레이션 | Nullable | 기본값 | 
| --- | --- | --- | --- | --- | 
| conn\$1sysid | 텍스트 | 없음 | Null이 아님 | 없음 | 
| conn\$1timeline | oid | 없음 | Null이 아님 | 없음 | 
| conn\$1dboid | oid | 없음 | Null이 아님 | 없음 | 
| conn\$1dsn | 텍스트 | 없음 | Null이 아님 | 없음 | 
| conn\$1apply\$1delay | 정수 | 없음 | 없음 | 없음 | 
| conn\$1replication\$1sets | 텍스트 | 없음 | 없음 | 없음 | 

conn\$1sysid  
이 항목이 참조하는 노드의 노드 식별자입니다.

conn\$1dsn  
pgactive.pgactive\$1nodes `node_dsn`과 동일합니다.

conn\$1apply\$1delay  
설정된 경우 원격 노드에서 각 트랜잭션을 적용하기 전에 기다릴 시간(밀리초)입니다. 주로 디버깅용입니다. null인 경우 글로벌 기본값이 적용됩니다.

## 복제 세트 작업
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replication"></a>

복제 세트는 복제 작업에서 포함하거나 제외할 테이블을 결정합니다. 기본적으로 달리 지정하지 않는 한 다음 함수를 사용하여 모든 테이블이 복제됩니다.
+ `pgactive_exclude_table_replication_set()` - 복제에서 지정된 테이블을 제외합니다.
+ `pgactive_include_table_replication_set()` - 복제에 지정된 테이블을 포함합니다.

**참고**  
복제 세트를 구성하기 전에 다음 사항을 고려하세요.  
`pgactive_create_group()`을 실행한 후 그리고 `pgactive_join_group()` 전에만 테이블 포함 또는 제외를 구성할 수 있습니다.
`pgactive_exclude_table_replication_set()`를 사용한 후에는 `pgactive_include_table_replication_set()`를 사용할 수 없습니다.
`pgactive_include_table_replication_set()`를 사용한 후에는 `pgactive_exclude_table_replication_set()`를 사용할 수 없습니다.

시스템은 초기 구성에 따라 새로 만들어진 테이블을 다르게 처리합니다.
+ 테이블을 제외한 경우: `pgactive_join_group()` 이후에 생성된 모든 새 테이블은 복제에 자동으로 포함됩니다.
+ 테이블을 포함한 경우: `pgactive_join_group()` 이후에 생성된 모든 새 테이블은 복제에서 자동으로 제외됩니다.

특정 테이블에 대한 복제 세트 구성을 보려면 `pgactive.pgactive_get_table_replication_sets()` 함수를 사용합니다.

# pgactive 함수 참조
<a name="pgactive-functions-reference"></a>

다음은 효과적으로 사용하기 위한 파라미터, 반환 값 및 실제 사용 정보가 포함된 pgactive 함수의 목록입니다.

## get\$1last\$1applied\$1xact\$1info
<a name="get-last-applied-xact-info"></a>

지정된 노드에 대해 마지막으로 적용된 트랜잭션 정보를 검색합니다.

**인수**  
+ sysid(텍스트) - 타임라인 OID
+ dboid(OID)

**반환 타입**  
다음을 기록합니다.  
+ last\$1applied\$1xact\$1id(OID)
+ last\$1applied\$1xact\$1committs(타임스탬프와 시간대)
+ last\$1applied\$1xact\$1at(타임스탬프와 시간대)

**사용 노트**  
이 함수를 사용하여 지정된 노드에 마지막으로 적용된 트랜잭션 정보를 검색합니다.

## pgactive\$1apply\$1pause
<a name="pgactive-apply-pause"></a>

복제 적용 프로세스를 일시 중지합니다.

**인수**  
없음

**반환 타입**  
boolean

**사용 노트**  
복제 적용 프로세스를 일시 중지하려면 이 함수를 직접적으로 호출합니다.

## pgactive\$1apply\$1resume
<a name="pgactive-apply-resume"></a>

복제 적용 프로세스를 재개합니다.

**인수**  
없음

**반환 타입**  
void

**사용 노트**  
복제 적용 프로세스를 재개하려면 이 함수를 직접적으로 호출합니다.

## pgactive\$1is\$1apply\$1paused
<a name="pgactive-is-apply-paused"></a>

복제 적용이 현재 일시 중지되었는지 확인합니다.

**인수**  
없음

**반환 타입**  
boolean

**사용 노트**  
이 함수를 사용하여 복제 적용이 현재 일시 중지되었는지 확인합니다.

## pgactive\$1create\$1group
<a name="pgactive-create-group"></a>

독립 실행형 데이터베이스를 초기 노드로 변환하여 pgactive 그룹을 만듭니다.



**인수**  
+ node\$1name(텍스트)
+ node\$1dsn(텍스트)
+ apply\$1delay 정수 DEFAULT NULL::정수 - replication\$1sets 텍스트[] DEFAULT ARRAY[‘default’::텍스트]

**반환 타입**  
void

**사용 노트**  
독립 실행형 데이터베이스를 초기 노드로 변환하여 pgactive 그룹을 만듭니다. 이 함수는 노드를 pgactive 노드로 변환하기 전에 무결성 검사를 수행합니다. 이 함수를 사용하기 전에 PostgreSQL 클러스터에 pgactive 백그라운드 작업자를 지원할 수 있는 충분한 `max_worker_processes`가 있는지 확인합니다.

## pgactive\$1detach\$1nodes
<a name="pgactive-detach-nodes"></a>

pgactive 그룹에서 지정된 노드를 제거합니다.

**인수**  
+ p\$1nodes(텍스트[])

**반환 타입**  
void

**사용 노트**  
이 함수를 사용하여 pgactive 그룹에서 지정된 노드를 제거합니다.

## pgactive\$1exclude\$1table\$1replication\$1set
<a name="pgactive-exclude-table-replication-set"></a>

복제에서 특정 테이블을 제외합니다.

**인수**  
+ p\$1relation(regclass)

**반환 타입**  
void

**사용 노트**  
이 함수를 사용하여 복제에서 특정 테이블을 제외합니다.

## pgactive\$1get\$1replication\$1lag\$1info
<a name="pgactive-get-replication-lag-info"></a>

노드 세부 정보, WAL 상태 및 LSN 값을 포함한 자세한 복제 지연 정보를 검색합니다.

**인수**  
없음

**반환 타입**  
SETOF 레코드 - node\$1name 텍스트 - node\$1sysid 텍스트 - application\$1name 텍스트 - slot\$1name 텍스트 - active 부울 - active\$1pid 정수 - pending\$1wal\$1decoding bigint - 전송자 노드에서 디코딩할 WAL의 대략적인 크기(바이트) - pending\$1wal\$1to\$1apply bigint - 수신 노드에서 적용할 WAL의 대략적인 크기(바이트) - restart\$1lsn pg\$1lsn - confirmed\$1flush\$1lsn pg\$1lsn - sent\$1lsn pg\$1lsn - write\$1lsn pg\$1lsn - flush\$1lsn pg\$1lsn - replay\$1lsn pg\$1lsn

**사용 노트**  
이 함수를 직접적으로 호출하여 노드 세부 정보, WAL 상태 및 LSN 값을 포함한 복제 지연 정보를 검색합니다.

## pgactive\$1get\$1stats
<a name="pgactive-get-stats"></a>

pgactive 복제 통계를 검색합니다.

**인수**  
없음

**반환 타입**  
SETOF 레코드 - rep\$1node\$1id oid - rilocalid oid - riremoteid text - nr\$1commit bigint - nr\$1rollback bigint - nr\$1insert bigint - nr\$1insert\$1conflict bigint - nr\$1update bigint - nr\$1update\$1conflict bigint - nr\$1delete bigint - nr\$1delete\$1conflict bigint - nr\$1disconnect bigint

**사용 노트**  
이 함수를 사용하여 pgactive 복제 통계를 검색합니다.

## pgactive\$1get\$1table\$1replication\$1sets
<a name="pgactive-get-table-replication-sets"></a>

특정 관계에 대한 복제 세트 구성을 가져옵니다.

**인수**  
+ 관계(regclass)

**반환 타입**  
SETOF 레코드

**사용 노트**  
이 함수를 직접적으로 호출하여 특정 관계에 대한 복제 세트 구성을 가져옵니다.

## pgactive\$1include\$1table\$1replication\$1set
<a name="pgactive-include-table-replication-set"></a>

복제에 특정 테이블을 포함합니다.

**인수**  
+ p\$1relation(regclass)

**반환 타입**  
void

**사용 노트**  
복제에 특정 테이블을 포함하려면 이 함수를 사용합니다.

## pgactive\$1join\$1group
<a name="pgactive-join-group"></a>

기존 pgactive 그룹에 노드를 추가합니다.

**인수**  
+ node\$1name(텍스트)
+ node\$1dsn(텍스트)
+ join\$1using\$1dsn(텍스트)
+ apply\$1delay(정수, 선택 사항)
+ replication\$1sets(텍스트[], 기본값: ['default'])
+ bypass\$1collation\$1check(부울, 기본값: false)
+ bypass\$1node\$1identifier\$1creation(부울, 기본값: false)
+ bypass\$1user\$1tables\$1check(부울, 기본값: false)

**반환 타입**  
void

**사용 노트**  
이 함수를 직접적으로 호출하여 기존 pgactive 그룹에 노드를 추가합니다. PostgreSQL 클러스터에 pgactive 백그라운드 작업자를 위한 충분한 max\$1worker\$1processes가 있는지 확인합니다.

## pgactive\$1remove
<a name="pgactive-remove"></a>

로컬 노드에서 모든 pgactive 구성 요소를 제거합니다.

**인수**  
+ force(부울, 기본값: false)

**반환 타입**  
void

**사용 노트**  
로컬 노드에서 모든 pgactive 구성 요소를 제거하려면 이 함수를 직접적으로 호출합니다.

## pgactive\$1snowflake\$1id\$1nextval
<a name="pgactive-snowflake-id-nextval"></a>

노드별 고유 시퀀스 값을 생성합니다.

**인수**  
+ regclass

**반환 타입**  
bigint

**사용 노트**  
이 함수를 사용하여 노드별 고유 시퀀스 값을 생성합니다.

## pgactive\$1update\$1node\$1conninfo
<a name="pgactive-update-node-conninfo"></a>

pgactive 노드의 연결 정보를 업데이트합니다.

**인수**  
+ node\$1name\$1to\$1update(텍스트)
+ node\$1dsn\$1to\$1update(텍스트)

**반환 타입**  
void

**사용 노트**  
이 함수를 사용하여 pgactive 노드의 연결 정보를 업데이트합니다.

## pgactive\$1wait\$1for\$1node\$1ready
<a name="pgactive-wait-for-node-ready"></a>

그룹 생성 또는 조인 작업의 진행 상황을 모니터링합니다.

**인수**  
+ timeout(정수, 기본값: 0)
+ progress\$1interval(정수, 기본값: 60)

**반환 타입**  
void

**사용 노트**  
이 함수를 직접적으로 호출하여 그룹 만들기 또는 조인 작업의 진행 상황을 모니터링합니다.

# 액티브-액티브 복제의 충돌 처리
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts"></a>

`pgactive` 확장은 클러스터별이 아니라 데이터베이스별로 작동합니다. `pgactive`를 사용하는 각 DB 인스턴스는 독립 인스턴스이며 모든 소스의 데이터 변경을 수락할 수 있습니다. 변경 사항이 DB 인스턴스로 전송되면 PostgreSQL은 변경 사항을 로컬에서 커밋한 다음 `pgactive`를 사용하여 변경 사항을 다른 DB 인스턴스에 비동기적으로 복제합니다. 두 PostgreSQL DB 인스턴스가 거의 동시에 같은 레코드를 업데이트하는 경우 충돌이 발생할 수 있습니다.

`pgactive` 확장은 충돌 감지 및 자동 해결을 위한 메커니즘을 제공합니다. 두 DB 인스턴스 모두에서 트랜잭션이 커밋된 시점의 타임스탬프를 추적하고 최신 타임스탬프와 함께 변경 사항을 자동으로 적용합니다. 또한 `pgactive` 확장은 `pgactive.pgactive_conflict_history` 테이블에서 충돌이 발생하는 경우에 이를 로깅합니다.

`pgactive.pgactive_conflict_history`는 계속 규모가 늘어납니다. 제거 정책을 정의할 수 있습니다. 정기적으로 일부 레코드를 삭제하거나 이 관계에 대한 파티션 스키마를 정의하여 수행할 수 있으며, 나중에 원하는 파티션을 분리, 삭제, 잘라낼 수 있습니다. 정기적으로 제거 정책을 구현하기 위한 한 가지 옵션은 `pg_cron` 확장을 사용하는 것입니다. [PostgreSQL pg\$1cron 확장을 사용하여 유지 관리 일정 예약](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html) `pg_cron` 기록 테이블에 대한 다음 예제 정보를 참조하세요.

# 액티브-액티브 복제의 시퀀스 처리
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences"></a>

`pgactive` 확장이 포함된 RDS for PostgreSQL DB 인스턴스는 서로 다른 두 개의 시퀀스 메커니즘을 사용하여 고유한 값을 생성합니다.

**글로벌 시퀀스**  
글로벌 시퀀스를 사용하려면 `CREATE SEQUENCE` 명령문을 사용하여 로컬 시퀀스를 생성합니다. 시퀀스의 다음 고유 값을 가져오려면 `usingnextval(seqname)` 대신 `pgactive.pgactive_snowflake_id_nextval(seqname)`을 사용합니다.

다음 예제에서는 글로벌 시퀀스를 생성합니다.

```
app=> CREATE TABLE gstest (
      id bigint primary key,
      parrot text
    );
```

```
app=>CREATE SEQUENCE gstest_id_seq OWNED BY gstest.id;
```

```
app=> ALTER TABLE gstest \
      ALTER COLUMN id SET DEFAULT \
      pgactive.pgactive_snowflake_id_nextval('gstest_id_seq');
```

**분할된 시퀀스**  
분할 단계 또는 분할된 시퀀스에서는 각 노드에 일반 PostgreSQL 시퀀스가 사용됩니다. 각 시퀀스는 같은 양만큼 증가하고 다른 오프셋에서 시작합니다. 예를 들어, 100단계에서 노드 1은 101, 201, 301 등의 시퀀스를 생성하고 노드 2는 102, 202, 302 등의 시퀀스를 생성합니다. 이 스키마는 노드가 장기간 통신할 수 없는 경우에도 잘 작동하지만 설계자가 스키마를 설정할 때 최대 노드 수를 지정해야 하며 노드별 구성이 필요합니다. 실수로 인해 시퀀스가 겹치기 쉽습니다.

다음과 같이 노드에 원하는 시퀀스를 생성하여 `pgactive`를 사용해 이 접근 방식을 비교적 간단히 구성할 수 있습니다.

```
CREATE TABLE some_table (generated_value bigint primary key);
```

```
app=> CREATE SEQUENCE some_seq INCREMENT 100 OWNED BY some_table.generated_value;
```

```
app=> ALTER TABLE some_table ALTER COLUMN generated_value SET DEFAULT nextval('some_seq');
```

그런 다음 각 노드에서 `setval`을 호출하여 다음과 같이 다른 오프셋 시작 값을 지정합니다.

```
app=>
-- On node 1
SELECT setval('some_seq', 1);

-- On node 2
SELECT setval('some_seq', 2);
```