본문으로 건너뛰기

10.1 한계와 알려진 결함

pg_auto_failover의 한계는 대부분 설계에서 비롯됩니다. 판정 기능을 monitor 하나에 모았고, 2노드에서는 데이터 이중화보다 서비스 지속을 우선합니다. 여기에 2026-09 시점의 상황도 고려해야 합니다. 최신 릴리스 v2.2 이후의 중요한 수정이 main에만 반영되어 있습니다. 이 장은 도입 전에 확인할 항목을 설계상 한계, 운영상 한계, 알려진 결함, 문서와 동작의 차이 순으로 정리합니다.

설계상 한계​

monitor는 control plane의 단일 장애점입니다. 데이터 경로에는 없으므로 monitor가 멈춰도 쓰기와 복제는 계속됩니다. 실측 결과, monitor가 멈춘 40초 동안 쓰기 실패는 0건이었습니다. 다만 그동안에는 failover, maintenance, 설정 변경, 노드 추가가 모두 불가능합니다. monitor가 멈춘 상태에서 primary를 kill하자 45초 동안 승격되지 않았습니다. monitor를 다시 시작한 뒤 46.3초 만에 새 primary가 나왔습니다(7.3).

monitor와 standby를 동시에 잃으면 상황이 달라집니다. keeper의 현재 상태가 primary이면 monitor와 standby에 모두 연결할 수 없을 때 스스로 PostgreSQL을 멈춥니다. 중단 시점은 network_partition_timeout(기본 20초)이 지난 뒤입니다(v2.2 service_keeper.c). 이미 wait_primary인 노드에는 이 검사가 적용되지 않습니다. 문서도 "3개 중 2개가 살아 있어야 가용성을 올바르게 지킬 수 있다"고 설명합니다. primary만 살아 있는 상황과 primary만 고립된 상황을 구분할 방법이 없기 때문입니다.

2노드 구성은 Business Continuity를 우선합니다. standby를 잃으면 primary는 wait_primary에서 비동기로 쓰기를 받습니다. 이어서 primary까지 잃으면 그사이의 쓰기는 해당 노드에만 남습니다. 자동 승격도 일어나지 않습니다(7.5). 데이터 두 벌을 항상 유지하려면 3노드 이상과 number_sync_standbys = 1이 필요합니다(5.4).

failover에는 오랜 시간이 걸리도록 설계되어 있습니다. 기본값에서 쓰기 공백은 2노드 51초, 3노드 54초였습니다. 이 중 30초는 이전 primary의 자체 강등을 기다리는 primary_demote_timeout입니다. 이 값을 줄이면 비대칭 네트워크 분리 상황에서 두 노드가 동시에 쓰기를 받는 구간이 생겼습니다(7.6).

운영상 한계​

  • 역할 판정용 REST API 없음. HAProxy나 PgBouncer 연동은 직접 구현(8.2)
  • Kubernetes native operator 없음. FAQ는 영구 볼륨을 연결한 채 다른 pod로 옮겨 재기동하는 monitor를 지원 사례로 제시하지만, 선언형 리소스로 클러스터를 관리하는 기능은 없음
  • PostgreSQL major 업그레이드 자동화 없음(6.7)
  • 백업, WAL 아카이빙, 지표 exporter 없음(Part IX)
  • monitor를 새로 만들고 재등록하면 candidate priority, number_sync_standbys, monitor GUC 같은 설정이 기본값으로 돌아감(실측, 6.6)

유지보수가 소수에게 집중되어 있다는 점도 운영 위험입니다. v2.1(2023-11)부터 v2.2(2025-04)까지 16개월이 걸렸고, 2024년에는 커밋이 없었습니다. v2.2 이후 main 커밋 61건 중 54건은 한 명이 작성했습니다(1.3).

main에서 고쳐졌지만 릴리스되지 않은 결함​

아래 내용은 git log v2.2..main의 커밋 제목에서 확인한 수정 사항입니다. 괄호 안은 PR 번호입니다. v2.2를 사용하는 동안 같은 증상이 나타날 수 있습니다.

PR내용
#11493개 데이터센터 구성의 split brain. 복제가 멈추면 monitor가 wait_primary를 지정(issue #997)
#1142모든 quorum 노드가 LSN을 보고하기 전 승격을 막는 guard_data_loss GUC, perform failover --allow-data-loss
#1143모든 WAL 원본이 unhealthy일 때 fast_forward 후보가 멈추는 문제 감지와 복구
#1158스스로 fencing한 primary가 도달할 수 없는 목표 상태에서 영원히 멈추는 문제(issue #1025)
#1161switchover 실패 뒤 복구할 수 없는 상태가 되는 timeline 분기(issue #683)
#1165failover 중 monitor가 primary에 도달할 수 없는 목표 상태를 지정하는 문제(issue #774)
#1169wait_primary에서 draining/demote_timeout으로 가는 전이가 keeper FSM에 없던 문제(issue #1168)
#1171monitor deadlock 시 perform failover 재시도
#1173좀비 postmaster를 살아 있는 것으로 오판하는 문제
#1174로그에 monitor 비밀번호가 남는 문제
#1180monitor 서버 쪽 TCP keepalive와 tcp_user_timeout

이 수정 사항을 포함한 릴리스가 언제 나올지는 2026-09-28 현재 알 수 없습니다. main을 직접 빌드해서 사용할 수도 있습니다. 다만 확장 버전이 2.3으로 바뀌고 ltree 의존성이 추가되는 등 v2.2와 호환되지 않는 부분이 있습니다. 따라서 업그레이드 절차를 별도로 검증해야 합니다.

경고

위 표는 커밋 제목과 PR 번호를 기준으로 정리했습니다. 이 문서에서는 각 결함을 v2.2에서 재현하지 않았습니다. 운영 중인 버전이 영향을 받는지는 해당 issue의 재현 조건에 따라 확인해야 합니다.

문서와 동작의 차이​

v2.2 태그의 문서에는 실제 동작과 다른 설명이 남아 있습니다.

  • number_sync_standbys = 0이면 synchronous_standby_names = '*'를 쓴다는 설명: 실측 값은 'ANY 1 (pgautofailover_standby_2)'. v1.5.1 CHANGELOG의 "wildcard 사용 중단"과 일치
  • fault-tolerance.rst의 "monitor는 새 primary 승격 전 90초 기다린다": v2.2 기본값은 primary_demote_timeout 30초이고 실측도 30초 대기
  • health check 결과를 보여 주는 Reachable 열: 실습의 show state에는 Connection 열과 ! 표시로 나옴

readthedocs의 main 문서는 여러 부분이 수정되었지만 v2.2에는 없는 기능 설명도 섞여 있습니다. v2.2를 운영한다면 태그 문서와 실제 출력을 함께 확인하는 것이 안전합니다.

정리​

monitor 하나에 판정 기능을 모은 설계 덕분에 구성은 단순합니다. 그러나 monitor는 control plane의 단일 장애점이고 failover는 50초 안팎으로 느립니다. 2노드는 서비스 지속을 우선합니다. 또한 v2.2 이후 반영된 split brain과 FSM 고착 문제의 수정 사항은 아직 릴리스되지 않았습니다. 이러한 현재 상황까지 고려해 도입을 판단해야 합니다.