콘텐츠로 이동

27.2. 로그 전송 스탠바이 서버 (PostgreSQL 비동기 복제)

출처: PostgreSQL 공식 문서 — 27장. 고가용성, 부하 분산 및 복제 지원 버전: Current (15) / 14 / 13 / 12 / 11 / 10


지속적 아카이빙(continuous archiving)은 기본 서버(primary server)가 장애를 일으킬 경우 운영을 이어받을 준비가 된 하나 이상의 스탠바이 서버(standby server)를 갖춘 고가용성(HA) 클러스터 구성을 만드는 데 사용할 수 있습니다. 이 기능은 웜 스탠바이(warm standby) 또는 로그 전송(log shipping) 이라고 널리 불립니다.

기본 서버와 스탠바이 서버는 함께 작동하여 이 기능을 제공하지만, 서버들은 느슨하게만 결합되어 있습니다. 기본 서버는 지속적 아카이빙 모드로 동작하며, 각 스탠바이 서버는 기본 서버에서 WAL 파일을 읽어 지속적 복구 모드로 동작합니다. 이 기능을 활성화하기 위해 데이터베이스 테이블을 변경할 필요가 없으므로, 다른 일부 복제 솔루션에 비해 관리 오버헤드가 낮습니다. 또한 기본 서버에 대한 성능 영향도 비교적 낮습니다.

WAL 레코드를 한 데이터베이스 서버에서 다른 서버로 직접 이동하는 것을 일반적으로 로그 전송이라고 합니다. PostgreSQL은 WAL 레코드를 한 번에 하나의 파일(WAL 세그먼트) 단위로 전송하는 파일 기반 로그 전송 방식을 구현합니다. WAL 파일(16MB)은 인접한 시스템, 동일 사이트의 다른 시스템, 또는 지구 반대편의 시스템으로도 쉽고 저렴하게 전송할 수 있습니다. 이 기술에 필요한 대역폭은 기본 서버의 트랜잭션 속도에 따라 달라집니다. 레코드 기반 로그 전송은 더 세밀하며 네트워크 연결을 통해 WAL 변경 사항을 점진적으로 스트리밍합니다(27.2.5절 참고).

참고: 로그 전송은 비동기적입니다 — WAL 레코드는 트랜잭션 커밋 이후에 전송됩니다. 따라서 기본 서버가 치명적 장애를 겪을 경우 데이터 손실이 발생할 수 있는 구간(window)이 존재합니다. 아직 전송되지 않은 트랜잭션은 손실됩니다. archive_timeout 파라미터를 몇 초까지 낮게 설정하면 파일 기반 로그 전송에서 데이터 손실 구간의 크기를 제한할 수 있습니다. 그러나 이렇게 낮게 설정하면 파일 전송에 필요한 대역폭이 크게 증가합니다. 스트리밍 복제(27.2.5절)를 사용하면 훨씬 더 작은 데이터 손실 구간을 허용합니다.

복구 성능은 충분히 좋기 때문에, 스탠바이가 활성화된 후 일반적으로 몇 초 안에 완전 가용 상태가 됩니다. 이로 인해 이를 웜 스탠바이 구성이라고 하며, 고가용성을 제공합니다. 아카이브된 기본 백업에서 서버를 복원하고 롤포워드하는 방식은 상당히 오래 걸리므로, 해당 기술은 고가용성이 아닌 재해 복구(disaster recovery) 솔루션에만 적합합니다. 스탠바이 서버는 읽기 전용 쿼리에도 사용할 수 있으며, 이 경우 핫 스탠바이(hot standby) 서버라고 합니다. 자세한 내용은 27.4절을 참고하세요.


목차


27.2.1. 계획

기본 서버와 스탠바이 서버를 최대한 유사하게 만드는 것이 일반적으로 좋습니다. 특히 데이터베이스 서버의 관점에서 그렇습니다. 테이블스페이스와 연관된 경로명은 수정 없이 그대로 전달되므로, 해당 기능을 사용한다면 기본 서버와 스탠바이 서버 모두 테이블스페이스에 대해 동일한 마운트 경로를 가져야 합니다. CREATE TABLESPACE 명령이 기본 서버에서 실행될 경우, 필요한 새 마운트 포인트는 명령 실행 전에 기본 서버와 모든 스탠바이 서버에 미리 생성되어야 합니다. 하드웨어가 정확히 동일할 필요는 없지만, 경험상 동일한 시스템 두 대를 유지하는 것이 서로 다른 시스템 두 대를 애플리케이션과 시스템의 수명 동안 유지하는 것보다 훨씬 쉽습니다. 어떠한 경우에도 하드웨어 아키텍처는 동일해야 합니다 — 예를 들어 32비트 시스템에서 64비트 시스템으로 전송하는 것은 동작하지 않습니다.

일반적으로 서로 다른 주요(major) PostgreSQL 릴리스 버전 간의 로그 전송은 불가능합니다. PostgreSQL 글로벌 개발 그룹은 마이너 릴리스 업그레이드 시 디스크 형식을 변경하지 않는 정책을 유지하므로, 기본 서버와 스탠바이 서버에서 서로 다른 마이너 릴리스를 실행해도 정상적으로 작동할 가능성이 높습니다. 그러나 이에 대한 공식 지원은 제공되지 않으므로, 기본 서버와 스탠바이 서버를 가능한 한 동일한 릴리스 버전으로 유지할 것을 권장합니다. 새 마이너 릴리스로 업데이트할 때는 스탠바이 서버를 먼저 업데이트하는 것이 가장 안전한 정책입니다 — 새 마이너 릴리스가 이전 마이너 릴리스의 WAL 파일을 읽을 수 있는 가능성이 그 반대의 경우보다 높기 때문입니다.


27.2.2. 스탠바이 서버 동작

서버가 시작될 때 데이터 디렉터리에 standby.signal 파일이 존재하면 스탠바이 모드로 진입합니다.

스탠바이 모드에서 서버는 기본 서버로부터 수신한 WAL을 지속적으로 적용합니다. 스탠바이 서버는 WAL 아카이브에서 WAL을 읽거나(restore_command 참고), TCP 연결을 통해 기본 서버에서 직접 읽을 수 있습니다(스트리밍 복제). 스탠바이 서버는 스탠바이 클러스터의 pg_wal 디렉터리에서 발견된 WAL도 복원하려 시도합니다. 이는 일반적으로 서버 재시작 후 발생하며, 스탠바이가 재시작 전에 기본 서버에서 스트리밍된 WAL을 다시 재생할 때 이루어집니다. 하지만 언제든지 pg_wal에 파일을 수동으로 복사하여 재생되도록 할 수도 있습니다.

시작 시, 스탠바이는 아카이브 위치에서 사용 가능한 모든 WAL을 복원하는 것부터 시작하며 restore_command를 호출합니다. 거기서 사용 가능한 WAL의 끝에 도달하고 restore_command가 실패하면, pg_wal 디렉터리에서 사용 가능한 WAL을 복원하려 시도합니다. 이것도 실패하고 스트리밍 복제가 구성되어 있다면, 스탠바이는 기본 서버에 연결하여 아카이브 또는 pg_wal에서 발견된 마지막으로 유효한 레코드부터 WAL 스트리밍을 시작하려 시도합니다. 그것도 실패하거나 스트리밍 복제가 구성되지 않았거나 연결이 나중에 끊어지면, 스탠바이는 1단계로 돌아가 아카이브에서 파일을 다시 복원하려 시도합니다. 이렇게 아카이브, pg_wal, 스트리밍 복제를 통한 재시도 루프는 서버가 중지되거나 트리거 파일에 의해 페일오버가 작동될 때까지 계속됩니다.

pg_ctl promote 실행, pg_promote() 호출, 또는 트리거 파일(promote_trigger_file) 발견 시 스탠바이 모드를 종료하고 서버가 일반 동작으로 전환됩니다. 페일오버 전에 아카이브 또는 pg_wal에서 즉시 사용 가능한 모든 WAL이 복원되지만, 기본 서버에 연결하는 시도는 하지 않습니다.


27.2.3. 스탠바이 서버를 위한 기본 서버 준비

26.3절에 설명된 대로 스탠바이에서 접근 가능한 아카이브 디렉터리로 기본 서버에 지속적 아카이빙을 설정합니다. 아카이브 위치는 기본 서버가 다운된 경우에도 스탠바이에서 접근할 수 있어야 합니다. 즉, 기본 서버가 아닌 스탠바이 서버 자체나 신뢰할 수 있는 다른 서버에 위치해야 합니다.

스트리밍 복제를 사용하려면, 스탠바이 서버에서의 복제 연결을 허용하도록 기본 서버에 인증을 설정해야 합니다. 즉, 역할(role)을 생성하고 pg_hba.conf에 데이터베이스 필드를 replication으로 설정한 적절한 항목을 추가합니다. 또한 기본 서버의 구성 파일에서 max_wal_senders를 충분히 큰 값으로 설정해야 합니다. 복제 슬롯을 사용할 경우, max_replication_slots도 충분히 높게 설정해야 합니다.

스탠바이 서버를 부트스트랩하기 위해 26.3.2절에 설명된 대로 기본 백업을 수행합니다.


27.2.4. 스탠바이 서버 설정

스탠바이 서버를 설정하려면, 기본 서버에서 가져온 기본 백업을 복원합니다(26.3.2절 참고). 스탠바이의 클러스터 데이터 디렉터리에 standby.signal 파일을 생성합니다. WAL 아카이브에서 파일을 복사하는 간단한 명령으로 restore_command를 설정합니다. 고가용성을 위해 여러 스탠바이 서버를 사용할 계획이라면, recovery_target_timelinelatest(기본값)로 설정되어 있는지 확인하여 다른 스탠바이로의 페일오버 시 발생하는 타임라인 변경을 스탠바이 서버가 따르도록 합니다.

참고: restore_command는 파일이 존재하지 않는 경우 즉시 반환해야 합니다. 서버는 필요한 경우 명령을 다시 재시도합니다.

스트리밍 복제를 사용하려면, 기본 서버에 연결하는 데 필요한 호스트 이름(또는 IP 주소)과 추가 정보를 포함한 libpq 연결 문자열로 primary_conninfo를 설정합니다. 기본 서버가 인증을 위해 비밀번호가 필요한 경우, primary_conninfo에 비밀번호도 지정해야 합니다.

고가용성을 위해 스탠바이 서버를 설정하는 경우, 페일오버 후 스탠바이 서버가 기본 서버로 동작하게 되므로 기본 서버와 동일하게 WAL 아카이빙, 연결 및 인증을 설정합니다.

WAL 아카이브를 사용하는 경우, archive_cleanup_command 파라미터를 사용하여 스탠바이 서버에 더 이상 필요하지 않은 파일을 제거함으로써 크기를 최소화할 수 있습니다. pg_archivecleanup 유틸리티는 일반적인 단일 스탠바이 구성에서 archive_cleanup_command와 함께 사용하도록 특별히 설계되었습니다(pg_archivecleanup 참고).

간단한 설정 예시:

primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass options=''-c wal_sender_timeout=5000'''
restore_command = 'cp /path/to/archive/%f %p'
archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'

스탠바이 서버는 몇 대든 운영할 수 있습니다. 스트리밍 복제를 사용한다면 기본 서버에서 max_wal_senders를 모두 동시에 연결할 수 있을 만큼 충분히 높게 설정해야 합니다.


27.2.5. 스트리밍 복제

스트리밍 복제는 스탠바이 서버가 파일 기반 로그 전송으로 가능한 것보다 더 최신 상태를 유지할 수 있도록 합니다. 스탠바이는 기본 서버에 연결하고, 기본 서버는 WAL 파일이 채워지기를 기다리지 않고 WAL 레코드가 생성되는 즉시 스탠바이에 스트리밍합니다.

스트리밍 복제는 기본적으로 비동기입니다(27.2.8절 참고). 이 경우, 기본 서버에서 트랜잭션이 커밋되는 시점과 변경 사항이 스탠바이에서 보이는 시점 사이에 약간의 지연이 있습니다. 그러나 이 지연은 파일 기반 로그 전송보다 훨씬 작으며, 스탠바이가 부하를 따라갈 만큼 충분히 강력하다는 가정 하에 일반적으로 1초 미만입니다. 스트리밍 복제를 사용하면 데이터 손실 구간을 줄이기 위해 archive_timeout이 필요하지 않습니다.

파일 기반 지속적 아카이빙 없이 스트리밍 복제를 사용하는 경우, 스탠바이가 수신하기 전에 서버가 오래된 WAL 세그먼트를 재활용할 수 있습니다. 이 경우 스탠바이는 새 기본 백업에서 다시 초기화해야 합니다. WAL 세그먼트가 너무 일찍 재활용되지 않도록 wal_keep_size를 충분히 큰 값으로 설정하거나, 스탠바이에 대한 복제 슬롯을 구성하여 이를 방지할 수 있습니다. 스탠바이에서 접근 가능한 WAL 아카이브를 설정한 경우, 스탠바이는 충분한 세그먼트를 유지하는 한 항상 아카이브를 사용하여 최신 상태를 따라잡을 수 있으므로 이러한 해결 방법이 필요하지 않습니다.

스트리밍 복제를 사용하려면, 27.2절에 설명된 대로 파일 기반 로그 전송 스탠바이 서버를 설정합니다. 파일 기반 로그 전송 스탠바이를 스트리밍 복제 스탠바이로 전환하는 단계는 primary_conninfo 설정이 기본 서버를 가리키도록 설정하는 것입니다. 기본 서버에서 listen_addresses와 인증 옵션(pg_hba.conf 참고)을 설정하여 스탠바이 서버가 기본 서버의 replication 의사 데이터베이스에 연결할 수 있도록 합니다(27.2.5.1절 참고).

keepalive 소켓 옵션을 지원하는 시스템에서 tcp_keepalives_idle, tcp_keepalives_interval, tcp_keepalives_count를 설정하면 기본 서버가 끊어진 연결을 신속하게 감지하는 데 도움이 됩니다.

스탠바이가 시작되고 primary_conninfo가 올바르게 설정된 경우, 스탠바이는 아카이브에서 사용 가능한 모든 WAL 파일을 재생한 후 기본 서버에 연결합니다. 연결이 성공적으로 수립되면 스탠바이에서 walreceiver를, 기본 서버에서 해당 walsender 프로세스를 볼 수 있습니다.

27.2.5.1. 인증

WAL 스트림에서 권한이 있는 정보를 추출하기 쉽기 때문에, 신뢰할 수 있는 사용자만 WAL 스트림을 읽을 수 있도록 복제에 대한 접근 권한을 설정하는 것이 매우 중요합니다. 스탠바이 서버는 REPLICATION 권한 또는 슈퍼유저 권한을 가진 계정으로 기본 서버에 인증해야 합니다. 복제를 위해 REPLICATIONLOGIN 권한을 가진 전용 사용자 계정을 생성하는 것을 권장합니다. REPLICATION 권한은 매우 높은 권한을 부여하지만, SUPERUSER 권한과 달리 기본 시스템의 어떤 데이터도 수정할 수 없습니다.

복제에 대한 클라이언트 인증은 database 필드에 replication을 지정하는 pg_hba.conf 레코드로 제어합니다. 예를 들어, 스탠바이가 호스트 IP 192.168.1.100에서 실행 중이고 복제용 계정 이름이 foo라면, 관리자는 기본 서버의 pg_hba.conf 파일에 다음 줄을 추가할 수 있습니다:

# 사용자 "foo"가 192.168.1.100에서 올바른 비밀번호를 제공하는 경우
# 기본 서버에 복제 스탠바이로 연결하는 것을 허용합니다.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    replication     foo             192.168.1.100/32        md5

기본 서버의 호스트 이름과 포트 번호, 연결 사용자 이름, 비밀번호는 primary_conninfo에 지정합니다. 비밀번호는 스탠바이의 ~/.pgpass 파일에 설정할 수도 있습니다(database 필드에 replication 지정). 예를 들어, 기본 서버가 호스트 IP 192.168.1.50, 포트 5432에서 실행 중이고, 복제용 계정 이름이 foo, 비밀번호가 foopass라면, 관리자는 스탠바이의 postgresql.conf 파일에 다음 줄을 추가할 수 있습니다:

# 스탠바이가 192.168.1.50 호스트와 포트 5432에서 실행 중인 기본 서버에
# "foo" 사용자로, 비밀번호 "foopass"를 사용하여 연결합니다.
primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'

27.2.5.2. 모니터링

스트리밍 복제의 중요한 상태 지표는 기본 서버에서 생성되었지만 아직 스탠바이에 적용되지 않은 WAL 레코드의 양입니다. 기본 서버의 현재 WAL 쓰기 위치와 스탠바이가 수신한 마지막 WAL 위치를 비교하여 이 지연(lag)을 계산할 수 있습니다. 이 위치들은 각각 기본 서버의 pg_current_wal_lsn과 스탠바이의 pg_last_wal_receive_lsn을 사용하여 조회할 수 있습니다(자세한 내용은 Table 9.88, Table 9.89 참고). 스탠바이의 마지막 WAL 수신 위치는 ps 명령을 사용하여 WAL 수신자 프로세스의 프로세스 상태에도 표시됩니다(28.1절 참고).

pg_stat_replication 뷰를 통해 WAL 전송자 프로세스 목록을 조회할 수 있습니다. pg_current_wal_lsn과 뷰의 sent_lsn 필드 사이의 큰 차이는 기본 서버가 과부하 상태임을 나타낼 수 있으며, 스탠바이의 sent_lsnpg_last_wal_receive_lsn 사이의 차이는 네트워크 지연 또는 스탠바이가 과부하 상태임을 나타낼 수 있습니다.

핫 스탠바이에서 WAL 수신자 프로세스의 상태는 pg_stat_wal_receiver 뷰를 통해 조회할 수 있습니다. pg_last_wal_replay_lsn과 뷰의 flushed_lsn 사이의 큰 차이는 WAL이 재생될 수 있는 속도보다 빠르게 수신되고 있음을 나타냅니다.


27.2.6. 복제 슬롯

복제 슬롯은 스탠바이가 연결이 끊긴 경우에도, 모든 스탠바이가 WAL 세그먼트를 수신할 때까지 기본 서버가 WAL 세그먼트를 제거하지 않도록 하고, 복구 충돌(recovery conflict)을 일으킬 수 있는 행을 기본 서버가 제거하지 않도록 하는 자동화된 방법을 제공합니다.

복제 슬롯 대신에 wal_keep_size를 사용하거나, archive_command 또는 archive_library를 통해 세그먼트를 아카이브에 저장하여 오래된 WAL 세그먼트의 제거를 방지할 수 있습니다. 그러나 이러한 방법은 필요한 것보다 더 많은 WAL 세그먼트를 유지하는 경우가 많은 반면, 복제 슬롯은 필요하다고 알려진 세그먼트 수만 유지합니다. 반면에 복제 슬롯은 너무 많은 WAL 세그먼트를 유지하여 pg_wal에 할당된 공간을 채울 수 있습니다. max_slot_wal_keep_size는 복제 슬롯이 유지하는 WAL 파일의 크기를 제한합니다.

마찬가지로, hot_standby_feedbackvacuum_defer_cleanup_age는 vacuum에 의해 관련 행이 제거되는 것에 대한 보호를 제공하지만, 전자는 스탠바이가 연결되지 않은 기간 동안 보호를 제공하지 않으며, 후자는 적절한 보호를 위해 높은 값으로 설정해야 하는 경우가 많습니다. 복제 슬롯은 이러한 단점을 극복합니다.

27.2.6.1. 복제 슬롯 조회 및 조작

각 복제 슬롯에는 이름이 있으며, 소문자, 숫자, 밑줄 문자를 포함할 수 있습니다.

기존 복제 슬롯과 상태는 pg_replication_slots 뷰에서 확인할 수 있습니다.

슬롯은 스트리밍 복제 프로토콜(55.4절 참고) 또는 SQL 함수(9.27.6절 참고)를 통해 생성 및 삭제할 수 있습니다.

27.2.6.2. 설정 예시

복제 슬롯 생성 예시:

postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot');
  slot_name   | lsn
--------------+-----
 node_a_slot  |

postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
  slot_name   | slot_type | active
--------------+-----------+--------
 node_a_slot  | physical  | f
(1 row)

이 슬롯을 사용하도록 스탠바이를 구성하려면, 스탠바이에서 primary_slot_name을 설정합니다. 간단한 예시:

primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
primary_slot_name = 'node_a_slot'

27.2.7. 계단식 복제

계단식 복제(cascading replication) 기능은 스탠바이 서버가 복제 연결을 수락하고 WAL 레코드를 다른 스탠바이에 스트리밍하여 릴레이 역할을 할 수 있도록 합니다. 이를 통해 기본 서버에 대한 직접 연결 수를 줄이고 사이트 간 대역폭 사용을 최소화할 수 있습니다.

수신자(receiver)이자 전송자(sender) 역할을 하는 스탠바이를 계단식 스탠바이(cascading standby) 라고 합니다. 기본 서버에 더 직접적으로 연결된 스탠바이를 업스트림 서버(upstream server), 더 멀리 있는 스탠바이 서버를 다운스트림 서버(downstream server) 라고 합니다. 계단식 복제는 다운스트림 서버의 수나 배열에 제한을 두지 않지만, 각 스탠바이는 단일 기본 서버에 연결되는 하나의 업스트림 서버에만 연결됩니다.

계단식 스탠바이는 기본 서버에서 수신한 WAL 레코드뿐만 아니라 아카이브에서 복원된 것도 전송합니다. 따라서 업스트림 연결의 복제 연결이 끊어지더라도, 새로운 WAL 레코드가 사용 가능한 한 다운스트림으로의 스트리밍 복제는 계속됩니다.

계단식 복제는 현재 비동기입니다. 동기 복제 설정(27.2.8절 참고)은 현재 계단식 복제에 영향을 미치지 않습니다.

업스트림 스탠바이 서버가 새 기본 서버로 승격되면, recovery_target_timelinelatest(기본값)로 설정된 경우 다운스트림 서버는 새 기본 서버에서 계속 스트리밍합니다.

계단식 복제를 사용하려면, 계단식 스탠바이가 복제 연결을 수락할 수 있도록 설정합니다(max_wal_senders, hot_standby 설정, 호스트 기반 인증 구성). 또한 다운스트림 스탠바이의 primary_conninfo가 계단식 스탠바이를 가리키도록 설정해야 합니다.


27.2.8. 동기 복제

PostgreSQL 스트리밍 복제는 기본적으로 비동기입니다. 기본 서버가 충돌하면 커밋된 일부 트랜잭션이 스탠바이 서버에 복제되지 않아 데이터 손실이 발생할 수 있습니다. 데이터 손실의 양은 페일오버 시점의 복제 지연에 비례합니다.

동기 복제는 트랜잭션의 모든 변경 사항이 하나 이상의 동기 스탠바이 서버로 전송되었음을 확인하는 기능을 제공합니다. 이는 트랜잭션 커밋이 제공하는 표준 수준의 내구성을 확장합니다. 이 보호 수준을 컴퓨터 과학 이론에서 2-safe 복제, synchronous_commitremotewrite로 설정된 경우 group-1-safe(그룹 안전, 1-안전)라고 합니다.

동기 복제를 요청하면, 쓰기 트랜잭션의 각 커밋은 커밋이 기본 서버와 스탠바이 서버 모두의 디스크에 있는 WAL에 기록되었다는 확인이 수신될 때까지 대기합니다. 데이터가 손실될 수 있는 유일한 가능성은 기본 서버와 스탠바이 서버 모두 동시에 충돌하는 경우입니다. 이는 서버 충돌 시 변경 사항이 손실되지 않는다는 사용자의 신뢰도를 크게 높이지만, 요청 트랜잭션의 응답 시간을 필연적으로 증가시킵니다. 최소 대기 시간은 기본 서버와 스탠바이 간의 왕복 시간입니다.

읽기 전용 트랜잭션과 트랜잭션 롤백은 스탠바이 서버의 응답을 기다릴 필요가 없습니다. 하위 트랜잭션(subtransaction) 커밋은 스탠바이 서버의 응답을 기다리지 않으며, 최상위 커밋만 대기합니다. 데이터 로딩이나 인덱스 빌드 같은 장시간 실행 작업은 최종 커밋 메시지까지 대기하지 않습니다.

동기 스탠바이는 물리적 복제 스탠바이 또는 논리적 복제 구독자일 수 있습니다. 또한 적절한 피드백 메시지를 전송하는 방법을 아는 다른 물리적 또는 논리적 WAL 복제 스트림 소비자일 수도 있습니다.

설정

동기 복제는 synchronous_standby_names를 비어 있지 않은 값으로 설정하여 활성화합니다. synchronous_commit은 기본값이므로 일반적으로 변경이 필요하지 않습니다(20.5.1절, 20.6.2절 참고). 이 설정은 스탠바이가 커밋 레코드를 영구 저장소에 기록했다는 확인을 기다리도록 각 커밋을 구성합니다. synchronous_commit은 개별 사용자가 설정할 수 있으므로, 특정 트랜잭션에 대해서만 동기 복제를 구성하는 것이 가능합니다.

커밋 레코드가 기본 서버의 디스크에 기록된 후, WAL 레코드가 스탠바이로 전송됩니다. 스탠바이는 새로운 WAL 데이터 배치가 디스크에 기록될 때마다 응답 메시지를 전송합니다(스탠바이에서 wal_receiver_status_interval이 0으로 설정된 경우 제외). synchronous_commitremoteapply로 설정된 경우, 스탠바이는 커밋 레코드가 재생되어 트랜잭션이 사용자에게 보일 때 응답 메시지를 전송합니다.

synchronous_commitremotewrite로 설정하면, 스탠바이가 커밋 레코드를 수신하고 자체 운영 체제에 기록했지만 스탠바이의 디스크에 플러시되지 않은 경우 각 커밋이 확인을 기다리게 됩니다. 이 설정은 on보다 약한 내구성 보장을 제공합니다. 스탠바이는 운영 체제 충돌 시(PostgreSQL 충돌이 아닌) 데이터를 손실할 수 있습니다. 그러나 트랜잭션의 응답 시간을 줄일 수 있으므로 실제로 유용한 설정입니다.

synchronous_commitremoteapply로 설정하면, 현재 동기 스탠바이들이 트랜잭션을 재생하여 사용자 쿼리에서 볼 수 있게 될 때까지 각 커밋이 대기합니다. 간단한 경우에 이는 인과적 일관성(causal consistency)이 있는 부하 분산을 허용합니다.

빠른 종료(fast shutdown)가 요청된 경우 사용자의 대기가 중단됩니다. 그러나 비동기 복제를 사용할 때와 같이, 현재 연결된 스탠바이 서버에 모든 미처리 WAL 레코드가 전송될 때까지 서버는 완전히 종료되지 않습니다.

동기 스탠바이 선택

각 트랜잭션의 커밋이 응답을 기다릴 동기 스탠바이 서버 목록은 synchronous_standby_names에 지정합니다. 이 파라미터는 또한 목록된 것들 중에서 동기 스탠바이를 선택하는 스탠바이 이름 목록과 방법(FIRST, ANY)을 지정합니다.

FIRST 방법은 우선순위 기반 동기 복제를 지정하며, 트랜잭션 커밋이 우선순위에 따라 선택된 요청된 수의 동기 스탠바이에 WAL 레코드가 복제될 때까지 대기하도록 합니다. 목록에서 이름이 앞에 나올수록 높은 우선순위가 부여되어 동기 스탠바이로 간주됩니다. 목록의 나중에 나타나는 다른 스탠바이 서버들은 잠재적 동기 스탠바이를 나타냅니다. 현재 동기 스탠바이 중 하나가 어떤 이유로든 연결을 끊으면, 즉시 다음으로 높은 우선순위의 스탠바이로 대체됩니다.

우선순위 기반 다중 동기 스탠바이를 위한 synchronous_standby_names 예시:

synchronous_standby_names = 'FIRST 2 (s1, s2, s3, s4)'

이 예시에서, 4개의 스탠바이 서버 S1, S2, S3, S4가 실행 중인 경우, 이름이 스탠바이 이름 목록에서 앞에 나타나는 S1과 S2가 동기 스탠바이로 선택됩니다. S3은 잠재적 동기 스탠바이이며 S1 또는 S2 중 하나가 실패할 경우 동기 스탠바이 역할을 맡습니다. S4는 목록에 이름이 없으므로 비동기 스탠바이입니다.

ANY 방법은 쿼럼 기반 동기 복제를 지정하며, 트랜잭션 커밋이 목록에서 요청된 수의 동기 스탠바이 중 적어도 하나에 WAL 레코드가 복제될 때까지 대기하도록 합니다.

쿼럼 기반 다중 동기 스탠바이를 위한 synchronous_standby_names 예시:

synchronous_standby_names = 'ANY 2 (s1, s2, s3)'

이 예시에서, 4개의 스탠바이 서버 S1, S2, S3, S4가 실행 중인 경우, 트랜잭션 커밋은 S1, S2, S3 중 적어도 두 개의 스탠바이로부터 응답을 기다립니다. S4는 목록에 이름이 없으므로 비동기 스탠바이입니다.

성능 고려 사항

동기 복제는 일반적으로 애플리케이션이 허용 가능하게 수행되도록 신중하게 계획하고 배치된 스탠바이 서버를 필요로 합니다. 확인 대기는 오버헤드를 추가하며, 동기 복제의 부주의한 사용은 응답 시간 증가와 더 높은 경합으로 인해 데이터베이스 애플리케이션의 성능을 저하시킵니다.

PostgreSQL은 애플리케이션 개발자가 복제를 통해 필요한 내구성 수준을 지정할 수 있도록 합니다. 이는 시스템 전체에 대해 지정할 수 있으며, 특정 사용자나 연결, 심지어 개별 트랜잭션에 대해서도 지정할 수 있습니다.

애플리케이션 수준(기본 서버)에서 동기 복제 옵션을 지정하면, 전체 작업 부하의 대부분을 느리게 하지 않고 가장 중요한 변경 사항에 대해서만 동기 복제를 제공할 수 있습니다.

고가용성 고려 사항

동기 스탠바이가 하나만 있는 경우, 해당 동기 스탠바이가 충돌하면 응답을 기다리는 트랜잭션 커밋이 완료되지 않을 수 있습니다. 이 경우 최선의 전략은 여러 동기 스탠바이를 두는 것입니다.

우선순위 기반 동기 복제에서는 목록에서 이름이 앞에 나타나는 스탠바이가 동기 스탠바이로 사용됩니다. 이 후에 나열된 스탠바이는 현재 스탠바이 중 하나가 실패할 경우 동기 스탠바이 역할을 맡습니다.

스탠바이가 처음 기본 서버에 연결될 때는 아직 제대로 동기화되지 않은 상태입니다. 이를 CATCHUP 모드라고 합니다. 스탠바이와 기본 서버 간의 지연이 처음으로 0에 도달하면 실시간 STREAMING 상태로 전환됩니다. 스탠바이가 생성된 직후에는 따라잡기 기간이 길 수 있습니다. 스탠바이가 종료되면 따라잡기 기간은 스탠바이가 다운되어 있던 시간에 따라 증가합니다. 스탠바이는 STREAMING 상태에 도달한 후에만 동기 스탠바이가 될 수 있습니다.

커밋이 확인을 기다리는 동안 기본 서버가 재시작되면, 해당 대기 중인 트랜잭션들은 기본 데이터베이스가 복구되면 완전히 커밋된 것으로 표시됩니다. 충돌 시점에 모든 스탠바이가 모든 미처리 WAL 데이터를 수신했는지 확인할 방법이 없습니다. 일부 트랜잭션은 기본 서버에서 커밋된 것으로 표시되더라도 스탠바이에서는 커밋된 것으로 표시되지 않을 수 있습니다.

기본 서버가 나머지 스탠바이 서버와 격리된 경우, 남은 다른 스탠바이 서버 중 가장 좋은 후보로 페일오버해야 합니다.


27.2.9. 스탠바이에서의 지속적 아카이빙

스탠바이 설정에서 지속적 아카이빙이 사용될 때, 두 가지 다른 시나리오가 있습니다: WAL 아카이브가 기본 서버와 스탠바이 간에 공유되거나, 스탠바이가 별도의 아카이브를 가질 수 있습니다.

스탠바이의 아카이브가 기본 서버의 아카이브와 별도인 경우, archive_modealways로 구성하면 스탠바이가 아카이브에서 복원하든 스트리밍 복제로 받든 상관없이 수신하는 모든 WAL 세그먼트에 대해 아카이브 명령을 호출합니다. 공유 아카이브도 유사하게 처리할 수 있지만, archive_command 또는 archive_library는 여러 서버가 동시에 아카이브에 기록하고 있다는 것을 인식해야 합니다. 이는 각 서버가 아카이브의 서버별 하위 디렉터리에 기록하거나, 아카이브 명령 또는 라이브러리가 기록 전에 아카이브 파일을 잠그고 내용을 확인하되 동일한 파일이 두 번 아카이브되면 성공을 반환하는 방식으로 처리할 수 있습니다. 두 서버가 동시에 동일한 파일을 아카이브하려 할 때 경쟁 조건(race condition)이 없어야 합니다.

archive_modeon으로 설정된 경우, 아카이버는 복구 또는 스탠바이 모드에서 활성화되지 않습니다. 스탠바이 서버가 승격되면 승격 후에 아카이빙을 시작하지만, 자신이 생성하지 않은 WAL이나 타임라인 히스토리 파일은 아카이브하지 않습니다. 아카이브에서 완전한 WAL 파일 시리즈를 얻으려면, 스탠바이에 도달하기 전에 모든 WAL이 아카이브되도록 해야 합니다. 이는 파일 기반 로그 전송의 경우 본질적으로 사실입니다(스탠바이는 아카이브에서 발견된 파일만 복원할 수 있음). 그러나 스트리밍 복제가 활성화된 경우에는 그렇지 않습니다. 서버가 복구 모드가 아닌 경우, onalways 모드 사이에는 차이가 없습니다.


PostgreSQL 공식 문서 — Copyright © 1996–2023 The PostgreSQL Global Development Group