본문으로 건너뛰기

9.1 백업과 아카이빙

replication은 백업이 아닙니다. primary에서 실수로 실행한 DELETE는 몇 밀리초 안에 모든 standby에 반영됩니다. pg_auto_failover는 standby를 생성하거나 재구축할 때 pg_basebackup을 직접 실행합니다. 하지만 재해 복구용 base backup 저장소와 WAL archive는 관리하지 않습니다. 따라서 pgBackRest, Barman, WAL-G 같은 도구를 별도로 구성해야 합니다. 이때는 primary가 바뀐다는 사실을 고려해야 합니다. 아카이빙과 백업이 "현재 primary"를 따라가도록 구성해야 합니다.

이 장은 공식 문서와 PostgreSQL 17 문서를 바탕으로 정리했습니다. 이 노트의 실습에서는 백업 도구를 구성하지 않았습니다. 도구별 절차는 Backup & DR 노트를 참고합니다.

pg_autoctl이 변경하지 않는 설정​

실습에서 pg_autoctl create postgres가 만든 postgresql-auto-failover.conf에는 wal_level = 'replica', wal_keep_size = '8 GB', max_wal_senders = 12 등이 있었습니다. 하지만 archive_mode와 archive_command는 없었습니다. 아카이빙은 사용자가 postgresql.conf에 직접 설정합니다. 운영 문서에 따르면 include 지시문은 postgresql.conf 맨 위에 놓입니다. 따라서 그 아래에 적은 값이 pg_auto_failover 설정보다 우선합니다.

모든 승격 후보에 같은 아카이빙 설정​

archive_mode = on이면 WAL 아카이빙은 primary에서만 실행됩니다. standby가 승격되는 순간부터 해당 노드의 archiver가 동작합니다. 따라서 승격 후보가 될 수 있는 모든 노드에 같은 archive_mode와 archive_command를 미리 설정합니다. 설정이 빠진 노드가 승격되면 그때부터 WAL이 아카이브에 쌓이지 않습니다. 그러면 PITR 가능 범위에 빈틈이 생깁니다.

# 모든 데이터 노드의 postgresql.conf (pgBackRest 예시)
archive_mode = on
archive_command = 'pgbackrest --stanza=appdb archive-push %p'

archive_mode = always로 설정하면 standby도 받은 WAL을 아카이빙합니다. 이 경우 여러 노드가 같은 WAL 세그먼트를 아카이브에 넣으려고 합니다. 따라서 archive_command는 같은 파일이 이미 있어도 성공하도록 멱등적이어야 합니다. PostgreSQL 문서는 archive_command가 기존 파일을 덮어쓰지 않도록 권고합니다. 파일 내용이 같으면 성공으로 처리하라고 안내합니다.

노트

failover 직후에는 새 primary의 timeline이 바뀝니다. 아카이브에는 새 timeline의 WAL과 .history 파일이 쌓입니다. 옛 primary가 분기 후에 만든 WAL은 버려집니다. 7.4 실측에서는 고립된 옛 primary가 받은 쓰기가 pg_rewind로 사라졌습니다. 옛 primary의 archiver가 해당 WAL을 이미 아카이빙했다면 쓰이지 않는 분기 timeline이 아카이브에 남습니다.

base backup 대상​

pgBackRest와 Barman은 백업을 받을 PostgreSQL 호스트를 설정 파일에 기록합니다. primary가 바뀌면 이 대상도 바뀌어야 합니다. 방법은 크게 두 가지입니다.

  • 모든 데이터 노드를 백업 도구 설정에 등록하고, 도구가 primary를 찾게 함(pgBackRest는 여러 pg-host를 두고 primary를 판별)
  • 8.2처럼 monitor 조회로 현재 primary를 확인해 백업 명령의 대상을 정함

standby에서 파일을 복사해 primary 부하를 줄이는 backup-from-standby 기능도 있습니다. 이 경우에도 WAL 시작과 종료 위치를 primary와 조정해야 합니다. 따라서 primary 연결 정보가 필요합니다. 도구별 세부 동작은 각 도구의 문서에서 확인해야 합니다.

replication slot과 WAL 보존​

pg_auto_failover는 pgautofailover_standby_<nodeid> 형식의 replication slot을 노드마다 유지합니다. standby가 오래 중단되면 primary의 slot이 WAL을 계속 보존합니다. 이로 인해 디스크가 가득 찰 수 있습니다. 실습 설정에는 wal_keep_size = '8 GB'만 있었고 max_slot_wal_keep_size는 없었습니다. 아카이브가 있어도 standby가 해당 WAL로 따라잡으려면 별도 설정이 필요합니다. restore_command나 백업 도구의 복원 설정을 구성해야 합니다. pg_auto_failover의 기본 재합류 경로는 pg_rewind입니다. pg_rewind가 실패하면 pg_basebackup을 사용하며 아카이브는 자동으로 연결하지 않습니다. slot 상한, 아카이빙, restore_command를 함께 설계합니다. 자세한 내용은 6.5에서 다룹니다.

monitor DB는 일반 백업으로 되살리지 않는다​

monitor의 pg_auto_failover DB도 PostgreSQL이므로 백업할 수 있습니다. 하지만 FAQ는 비동기 백업으로 복원한 monitor를 권하지 않습니다. monitor의 노드 상태는 각 keeper가 마지막으로 받은 목표 상태와 정확히 일치해야 합니다. 몇 초 전의 백업이라도 그사이에 failover가 일어났을 가능성이 있습니다. 그러면 monitor와 노드가 서로 다른 primary를 신뢰하게 됩니다.

FAQ가 제시하는 선택지는 둘입니다.

  1. 동기 아카이빙: 정기 pg_basebackup과 pg_receivewal --sync를 서비스로 실행합니다. --sync만 사용하면 commit은 receiver를 기다리지 않습니다. 따라서 receiver의 application_name을 monitor의 synchronous_standby_names에 넣어야 합니다. 그래야 "커밋된 모든 트랜잭션이 아카이브에 있다"는 보장이 성립합니다. synchronous_commit = remote_apply에는 사용할 수 없습니다(6.6)
  2. 새 monitor 재등록: 새 monitor를 만들고 각 노드에서 pg_autoctl disable monitor, enable monitor로 다시 등록

실습에서는 2번을 실행했고 150초 동안 쓰기 실패가 0건이었습니다. 대신 candidate priority 같은 복제 설정은 기본값으로 돌아갔습니다. 절차는 6.6에 있습니다.

경고

monitor 백업은 "그냥 pg_dump로 받아 두면 된다"고 생각하기 쉽습니다. 오래된 상태로 복원된 monitor가 이미 강등된 노드를 primary로 인식할 위험이 있습니다. 그러면 keeper들이 받은 목표 상태와 충돌해 FSM이 진행되지 않을 위험이 있습니다. monitor는 백업 복원보다 재등록 절차를 미리 연습해 두는 편이 안전합니다.

정리​

pg_auto_failover 환경의 백업은 primary가 바뀐다는 전제에서 설계합니다. archive_command를 모든 승격 후보에 미리 설정합니다. 또한 백업 도구가 현재 primary를 찾을 방법을 마련합니다. monitor는 일반 백업 복원보다 새 monitor 재등록이나 동기 아카이빙을 준비합니다.