6.6 monitor 장애 복구와 교체
monitor가 멈춰도 복제와 쓰기는 계속됩니다. 하지만 그동안 failover와 모든 운영 명령이 멈춥니다(7.3). 따라서 monitor를 서둘러 복구해야 하지만, 방법을 잘못 선택하면 오히려 위험합니다. monitor의 데이터는 "각 노드가 마지막으로 받은 목표 상태"와 정확히 일치해야 의미가 있기 때문입니다. v2.2 FAQ와 운영 문서에서는 세 가지 경우를 제시합니다.
세 가지 복구 상황
첫째, 디스크가 남아 있는 경우입니다. 서버를 재부팅하거나 같은 영구 볼륨을 다른 서버에 연결해 다시 실행하면 됩니다. FAQ에서는 Kubernetes에서 pod가 이동한 뒤 볼륨을 다시 연결하는 상황을 예로 듭니다. 이 경우에는 별도의 개입이 필요 없다고 설명합니다. 실습에서는 monitor를 stop한 뒤 start했습니다. 그동안 중지된 primary에 대한 failover는 재기동 46.3초 뒤에 완료되었습니다.
둘째, 동기 WAL 아카이브를 운영하는 경우입니다. FAQ에서는 pg_basebackup으로 주기적인 전체 백업을 만들고, pg_receivewal --sync로 monitor의 WAL을 계속 받도록 권장합니다. 다만 --sync는 receiver 쪽 flush를 의미할 뿐입니다. monitor의 commit이 receiver를 기다리게 하지는 않습니다. receiver의 application_name을 monitor의 synchronous_standby_names에 넣어 synchronous replication으로 구성해야 합니다. 그래야 "커밋된 트랜잭션은 모두 아카이브에 있다"는 보장이 성립합니다. FAQ에서도 "synchronous replication을 쓰는 아카이빙"이라고 표현합니다. 복원 도구는 직접 만들어야 하며, v2.2에는 이 기능이 내장되어 있지 않습니다.
셋째, 아무것도 없는 경우입니다. 새 monitor를 만들고 노드를 온라인으로 다시 등록합니다. 이 노트에서 실습한 방법입니다.
일반적인 비동기 백업(예: 하루 전 pg_dump나 비동기 아카이브)으로 monitor를 복원하면 안 됩니다. 복원된 monitor는 과거의 primary와 목표 상태를 기억합니다. 그사이에 failover가 있었다면 monitor는 현재 standby를 primary로 인식하고 있을 수 있습니다. keeper들은 그 목표 상태를 따르려고 합니다. FAQ에서 동기 아카이브 또는 신규 재등록만 제시하는 이유입니다.
신규 monitor로 교체하기 (실측)
2노드 구성(node2 primary, node1 secondary)에서 writer를 150초 동안 실행하며 진행했습니다.
# 1. 옛 monitor 제거 (실습에서는 컨테이너와 볼륨 삭제로 소실을 흉내 냄)
docker compose rm -sf monitor
docker volume rm pgaf-lab_monitor-data
# 2. 모든 노드에서, pg_autoctl 이 실행 중인 상태로 (secondary 먼저, 현재 primary 는 마지막)
pg_autoctl disable monitor --force
# 3. 새 monitor 생성
docker compose up -d monitor
# 4. primary 먼저, 그다음 secondary
pg_autoctl enable monitor 'postgres://autoctl_node@monitor:5432/pg_auto_failover?sslmode=require'
-- disable monitor --force on node1
06:11:10 1608 INFO Failed to contact the monitor, disabling it as requested
new monitor ready 1.3s
-- enable monitor on node2
06:11:13 1710 INFO Registered node 2 "node2" (node2:5432) in formation "default", group 0, state "single"
06:11:13 1710 INFO Successfully registered to the monitor with nodeId 2
-- enable monitor on node1
06:11:13 1627 INFO Registered node 1 "node1" (node1:5432) in formation "default", group 0, state "wait_standby"
06:11:13 1627 INFO Successfully registered to the monitor with nodeId 1
node2 reached primary in 3.7s
writer: 664 ok, 0 FAIL, longest gap between ok starts 0.25s
전체 과정에서 INSERT 실패는 0건이었습니다. primary를 먼저 등록해야 하는 이유는 로그에서 확인할 수 있습니다. 먼저 등록한 node2는 single로 등록되어 primary 역할을 유지했습니다. 이어서 등록한 node1은 wait_standby로 등록되어 standby가 되었습니다. v2.2 운영 문서에서도 primary가 "여전히 primary로" 먼저 등록되도록 이 순서를 요구합니다. 순서를 바꾼 경우는 실습하지 않았습니다. node1은 catchingup을 잠시 거친 뒤, pg_basebackup 없이 secondary로 돌아왔습니다.
06:11:15 11 INFO FSM transition from "secondary" to "catchingup": Failed to report back to the monitor, not eligible for promotion
06:11:18 11 INFO FSM transition from "catchingup" to "secondary": Convinced the monitor that I'm up and running, and eligible for promotion again
교체 후 반드시 확인할 사항
새 monitor는 빈 데이터베이스에서 시작합니다. 노드 id와 상태는 재등록 과정에서 다시 만들어집니다. 하지만 옛 monitor에 있던 설정은 복구되지 않습니다.
- formation의
number_sync_standbys - 노드별 candidate priority와 replication quorum
- monitor의
pgautofailover.*GUC 조정값(ALTER SYSTEM또는postgresql.conf) - monitor의
pg_hba.conf, 인증서,autoctl_node비밀번호
실습에서도 교체 후 show settings는 기본값(number_sync_standbys 0, priority 50, quorum true)을 표시했습니다. 운영 환경에서는 이 값들을 코드나 설정 관리 도구에 보관해야 합니다. 교체 직후에는 저장해 둔 값을 다시 적용해야 합니다.
v2.2 운영 문서에서는 교체 절차의 첫 단계로 옛 monitor를 확실히 fencing(STONITH)하라고 명시합니다. 옛 monitor가 교체 도중 다시 실행되면 일부 노드가 옛 monitor를 따를 위험이 있습니다. 실습에서는 컨테이너와 볼륨을 삭제해 이 조건을 충족했습니다.
정리
monitor 복구 방법은 데이터가 남아 있으면 재기동, 동기 아카이브가 있으면 복원, 둘 다 없으면 신규 monitor에 재등록하는 순서로 선택합니다. 재등록은 쓰기 중단 없이 끝났습니다. 하지만 복제 설정과 monitor GUC는 기본값으로 돌아가므로 다시 적용해야 합니다.