5.3 replica 생성
DCS에 initialize 키가 있는 상태에서 빈 데이터 디렉토리로 시작한 노드는 bootstrap 대신 replica 생성 절차를 밟는다(5.1의 분기). 어떤 방법으로 데이터를 복사할지는 postgresql.create_replica_methods가 정하고, 목록이 비어 있으면 pg_basebackup을 쓰는 basebackup이 기본이다.
create_replica_methods 계약
create_replica_methods는 시도할 방법의 ordered list다. Patroni는 목록을 위에서부터 순서대로 실행하고, exit code 0을 반환하는 첫 번째 방법에서 멈춘다. 전부 실패하면 다음 HA loop cycle에 처음부터 다시 시도한다.
postgresql:
create_replica_methods:
- pgbackrest
- basebackup
flowchart TD
NEED["replica 생성 필요"] --> M1["method 1 실행"]
M1 -->|exit 0| OK["replica 구성, 시작"]
M1 -->|실패| M2["method 2 실행"]
M2 -->|exit 0| OK
M2 -->|실패| REST["나머지 순서대로"]
REST -->|전부 실패| RETRY["다음 loop cycle에<br/>처음부터 재시도"]
RETRY --> M1
bootstrap method가 체이닝 없이 단판 승부인 것과 달리, replica 생성은 목록 순서대로 fallback이 이어진다는 점이 두 계약의 가장 큰 차이다.
Patroni가 스크립트에 전달하는 것
각 method는 같은 이름의 설정 섹션이 필요하고, 최소한 command를 가진다. Patroni는 command에 네 가지 인자를 --name=value 형식으로 전달한다.
| 인자 | 값 |
|---|---|
--scope | 클러스터 이름 |
--datadir | replica data directory 경로 |
--role | 항상 replica |
--connstring | 복제 소스 멤버(primary 또는 다른 replica) 접속 문자열 |
--connstring에 담긴 계정은 SQL 명령과 replication protocol 명령을 모두 실행할 수 있다. 설정 섹션에 적은 사용자 정의 key: value도 같은 --name=value 형식으로 뒤에 붙는다.
동작을 바꾸는 특수 파라미터가 세 개 있다.
no_leader: 정의하면 leader가 없어도 method를 호출한다. 이때--connstring은 빈 문자열이다. 백업 저장소처럼 클러스터 밖의 소스에서 복원하는 method를 위한 옵션이다.keep_data: True: method 호출 전에 PGDATA를 지우지 않는다. 기존 파일을 재활용하는 delta restore류 도구와 짝을 이룬다.no_params: True: 위 파라미터 전달을 생략한다.
기본 method basebackup
별도 설정 없이도 동작한다. 복사 소스는 leader다. 단 clonefrom tag가 true인 replica가 하나라도 있으면 leader 대신 그쪽에서 pg_basebackup을 뜨고, 여럿이면 랜덤으로 하나를 고른다. leader의 복사 부하를 replica로 돌리고 싶은 배치에서 쓰는 tag다.
pg_basebackup에 옵션을 넘기려면 postgresql.basebackup 섹션을 쓴다. map과 list 두 형식을 지원하며, 값이 없는 플래그 옵션은 list 형식으로 섞는다.
# map 형식
postgresql:
basebackup:
max-rate: '100M'
checkpoint: 'fast'# list 형식 (값 없는 옵션 혼용)
postgresql:
basebackup:
- verbose
- max-rate: '100M'
- waldir: /pg-wal-mount/external-waldir--waldir를 직접 지정해야 한다(PostgreSQL 10 이상).replicatefrom tag와 cascading replication
tags.replicatefrom에 다른 replica의 멤버 이름을 지정하면, 그 노드를 복제 소스로 삼는 cascading replication이 된다.
tags:
replicatefrom: node2clonefrom과는 역할이 다르다. clonefrom은 “나를 복사 소스로 써도 좋다"고 알리는 tag고, replicatefrom은 “나는 저 노드에서 복제하겠다"고 선언하는 tag다. 전자는 초기 데이터 복사의 소스 선택에, 후자는 어느 노드에서 streaming으로 WAL을 받을지에 작용한다. replica를 새로 만드는 시점에 두 tag가 어떻게 상호작용하는지는 공식 문서에 상세가 없다.
백업 도구로 대체
replica를 만들 때마다 소스 노드에서 전체 복사를 뜨는 대신, 백업 저장소에서 복원하도록 바꾸는 구성이 널리 쓰인다. 공식 문서의 pgBackRest 예시가 이 패턴이다.
postgresql:
create_replica_methods:
- pgbackrest
- basebackup
pgbackrest:
command: /usr/bin/pgbackrest --stanza=demo --delta restore
keep_data: True
no_params: True
basebackup:
max-rate: '100M'--delta restore는 checksum 비교로 재사용 가능한 파일을 남기므로 keep_data: True와 짝을 이루고, pgBackRest는 --scope 같은 Patroni 인자를 받지 않는 외부 명령이므로 no_params: True로 전달을 끈다. WAL-E 예시도 문서에 있다.
postgresql:
create_replica_methods:
- wal_e
- basebackup
wal_e:
command: patroni_wale_restore
no_leader: 1
envdir: /etc/wal_e/env
use_iam: 1두 예시 모두 마지막에 basebackup을 fallback으로 병기한다. 백업 저장소 복원이 실패해도 소스 노드 직접 복사로 replica를 만들 수 있게 하는 안전망이다. WAL archive 연동을 포함한 백업 도구 통합의 전체 그림은 10.5 백업 도구 통합에서 다룬다.
정리
- replica 생성은
create_replica_methods목록을 순서대로 시도하고 exit 0에서 멈춘다. 전부 실패하면 다음 loop cycle에 재시도한다. - Patroni는
--scope,--datadir,--role=replica,--connstring네 인자를 전달하고,no_leader,keep_data,no_params로 계약을 조정한다. - 기본 basebackup의 소스는 leader이며
clonefromtag로 바꾼다. 백업 도구로 대체할 때는basebackup을 fallback으로 남겨 두는 구성이 일반적이다.