6.2 후보 선정
leader race에서 “최적 후보"는 누가 정해 주는 것이 아니다. 각 노드가 같은 규칙으로 자신을 검사해, 스스로 자격이 있다고 판단한 노드만 leader key 취득을 시도한다. 공식 문서는 이 과정을 개요 수준으로만 서술하므로, 이 절의 검사 순서는 Patroni 소스 코드(ha.py의 _is_healthiest_node, fetch_node_status)로 검증한 내용이다.
자격 검사 순서
한 노드가 자신을 후보로 판정하기까지 통과해야 하는 관문은 다음과 같다.
nofailover tag 검사
nofailover: true인 노드는 즉시 탈락한다. leader 자격 판정에서 항상 unhealthy로 취급된다.
PostgreSQL 기동 상태 검사
PostgreSQL이 아직 starting 상태면 탈락한다. WAL position을 신뢰할 수 없는 상태이기 때문이다.
timeline 검사 (선택)
check_timeline(기본 false)이 켜져 있으면, 자신의 timeline이 DCS에 기록된 클러스터의 마지막 timeline보다 낮은 노드는 탈락한다. 이전 primary와 timeline이 갈라진 노드가 leader가 되는 것을 막는 옵션이다.
replication lag 검사
자신의 WAL position이 DCS에 기록된 마지막 leader 위치(/status key의 last_lsn)보다 maximum_lag_on_failover(기본 1048576바이트, 1MiB) 넘게 뒤처져 있으면 탈락한다. 문서 정의 그대로 “leader election에 참여할 수 있는 최대 lag"이다.
다른 멤버와 WAL position 비교
살아남은 노드는 다른 멤버들의 GET /patroni 응답을 수집해 WAL position을 비교한다. 자신보다 앞선 노드가 하나라도 있으면 탈락한다.
동률이면 failover_priority
WAL position이 같은 노드가 여럿이면 failover_priority가 더 높은 쪽에 양보한다. 자신의 priority가 상대보다 낮으면 탈락한다.
flowchart TD
A["leader race 참가"] --> B{"nofailover: true?"}
B -->|예| X["후보 탈락"]
B -->|아니오| C{"PostgreSQL starting?"}
C -->|예| X
C -->|아니오| D{"timeline 뒤처짐?"}
D -->|예| X
D -->|아니오| E{"lag 1MiB 초과?"}
E -->|예| X
E -->|아니오| F{"더 앞선 멤버 존재?"}
F -->|예| X
F -->|아니오| G{"동률에서 priority 열세?"}
G -->|예| X
G -->|아니오| H["leader key 취득 시도"]
timeline 검사는 check_timeline을 켠 경우에만, 동률 비교는 failover_priority를 설정한 경우에만 의미가 있다.
WAL position은 어떻게 계산하나
비교에 쓰는 replica의 WAL position은 receive LSN과 replay LSN 중 큰 값이다.
# ha.py (fetch_node_status)
lsn = int(in_recovery and max(wal.get('received_location', 0),
wal.get('replayed_location', 0)))받아만 두고 아직 replay하지 않은 WAL도 그 노드의 진도로 인정한다는 뜻이다. replay가 느린 노드라도 WAL을 디스크에 확보해 두었다면 promote 후 마저 적용하면 되므로, 데이터 보존 관점에서는 receive 기준이 타당하다.
nofailover와 failover_priority
두 tag는 같은 축의 다른 표현이다.
| 설정 | 의미 |
|---|---|
nofailover: true | failover_priority: 0과 기능상 동일 |
nofailover: false | failover_priority: 1과 기능상 동일 |
failover_priority: 0 이하 | leader race 참여 불가 |
failover_priority: 2 이상 | WAL 동률일 때 1인 노드보다 우선 |
# patroni.yml (리포트용 replica 예시)
tags:
nofailover: true
# patroni.yml (동률일 때 우선하고 싶은 노드 예시)
tags:
failover_priority: 2failover_priority는 quorum 기반 synchronous replication과 호환되지 않는다고 문서에 명시되어 있다. synchronous_mode: quorum(6.5 quorum commit)을 쓰는 클러스터에서는 이 tag로 승격 우선순위를 통제할 수 없다. 또한 priority는 어디까지나 WAL position 동률일 때의 타이브레이커다. priority가 아무리 높아도 lag 검사나 position 비교에서 밀리면 탈락한다.synchronous_mode가 켜진 클러스터에서는 후보 풀 자체가 좁아진다. 마지막으로 알려진 leader이거나 synchronous replica인 노드만 leader race에 참여할 수 있다. 상세한 조건은 6.4 synchronous mode에서 다룬다.정리
후보 선정은 nofailover, 기동 상태, timeline, lag 한도라는 절대 조건을 먼저 거르고, 남은 노드끼리 WAL position을 비교해 가장 앞선 쪽이 이기는 구조다. failover_priority는 완전 동률일 때만 개입하는 마지막 타이브레이커이며, 이 순서를 알아야 “priority를 줬는데 왜 다른 노드가 승격됐나” 같은 상황을 설명할 수 있다.