본문으로 건너뛰기

3.5 maintenance, 설정 변경, 삭제 전이

장애 이외의 이유로 상태가 바뀌는 경우는 세 가지입니다. 운영자가 노드를 maintenance로 전환하는 경우가 있습니다. 복제 설정을 변경해 primary의 synchronous_standby_names를 다시 계산해야 하는 경우도 있습니다. 또한 노드를 group에서 삭제하는 경우가 있습니다. 세 경우 모두 monitor가 상태 머신으로 전이 순서를 제어합니다. 이 장에서는 각 전이의 상태 이름과 실측 결과를 정리합니다. 명령 사용법은 6.3과 6.4에 있습니다.

secondary maintenance​

경로를 구분하는 기준은 노드 수가 아닙니다. number_sync_standbys가 0이면서 대상이 마지막 healthy quorum standby인지가 기준입니다(start_maintenance). 2노드의 secondary가 대표적인 경우입니다. 이 standby를 제외하면 primary의 동기 복제가 중단되므로 순서가 필요합니다. standby는 wait_maintenance에서 대기합니다. primary가 wait_primary(동기 복제 해제)에 도달하면 maintenance로 전환됩니다. 운영 문서의 예시 출력도 이 순서를 보여 줍니다.

다른 healthy quorum standby가 있으면 해당 노드가 동기 복제를 이어받습니다. number_sync_standbys가 1 이상인 상태에서 필요한 standby를 제외하면 명령은 경고만 남기고 진행합니다. 따라서 쓰기가 중단될 수 있습니다. 실측에서 node3은 secondary에서 곧바로 maintenance로 전환되었습니다. primary는 primary 상태를 유지했습니다. 명령은 0.5초 뒤 반환했습니다.

05:38:18 | node3 | 3 | node3:5432 | secondary | maintenance
05:38:18 | node3 | 3 | node3:5432 | maintenance | maintenance
node1 | 1 | node1:5432 | 7: 0/903F8F0 | read-write | primary | primary
node2 | 2 | node2:5432 | 7: 0/9000000 | read-only | secondary | secondary
node3 | 3 | node3:5432 | 7: 0/903F8F0 | none | maintenance | maintenance

ssn=[ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3)]

maintenance 중에도 node3의 PostgreSQL은 실행 중이었습니다(pg_is_in_recovery()가 true). v2.2 keeper의 fsm_start_maintenance_on_standby()는 PostgreSQL을 중지하지 않습니다. keeper의 PostgreSQL 관리만 중단합니다. 소스 주석은 "이제 사용자가 서비스를 운전한다"고 설명합니다. 커널 업그레이드처럼 PostgreSQL을 중지해야 하는 작업은 운영자가 직접 중지합니다. synchronous_standby_names 목록에도 standby_3이 남아 있었습니다. ANY 1이므로 node2의 응답만으로 commit이 완료됩니다. 따라서 쓰기에는 영향을 주지 않았습니다.

disable maintenance를 실행하면 catchingup을 거쳐 secondary로 돌아옵니다. 실측에서는 1.4초가 걸렸습니다.

primary maintenance​

primary를 maintenance로 전환하는 것은 곧 failover입니다. 따라서 --allow-failover가 필요합니다. 2노드에서는 primary가 prepare_maintenance로 전환되며 PostgreSQL을 중지합니다. standby는 prepare_promotion, stop_replication을 거쳐 wait_primary가 됩니다. 그러면 이전 primary는 maintenance에 도달합니다(운영 문서 예시).

3노드에서는 선출이 필요하므로 report_lsn부터 시작합니다. 다음은 실측 출력입니다.

05:38:26 | node2 | 2 | node2:5432 | secondary | report_lsn
05:38:26 | node3 | 3 | node3:5432 | secondary | report_lsn
05:38:27 | node2 | 2 | node2:5432 | report_lsn | prepare_promotion
05:38:27 | node1 | 1 | node1:5432 | maintenance | maintenance

명령은 1.7초 뒤 반환했고 쓰기 공백은 3.74초였습니다. 명령은 이전 primary가 maintenance를 보고하면 반환합니다. 따라서 새 primary의 승격 완료 여부는 별도로 확인해야 합니다. 장애 failover와 달리 이전 primary가 계속 응답합니다. 따라서 primary_demote_timeout을 기다리지 않습니다.

apply_settings​

복제 설정(number_sync_standbys, replication quorum, candidate priority)이 바뀌면 primary의 synchronous_standby_names를 다시 작성해야 합니다. 이때 monitor는 primary에 apply_settings를 지정합니다. keeper가 새 값을 적용하고 보고하면 다시 primary로 돌아갑니다. 세 번째 노드가 합류할 때도 같은 경로를 사용합니다.

05:31:28.902|node2|primary|apply_settings|Setting goal state of node 3 "node3" (node3:5432) to catchingup and node 2 "node2" (node2:5432) to primary to edit synch
05:31:30.054|node2|apply_settings|primary|Setting goal state of node 2 "node2" (node2:5432) to primary after it applied replication properties change.

monitor는 설정을 적용하기 전에 결과가 안전한지 검사합니다. 다음은 실측에서 거부된 요청과 메시지입니다.

Monitor ERROR: can't set replication quorum to false
Monitor DETAIL: At least 2 standby nodes are required in formation default with number_sync_standbys = 1, and only 1 would be participating in the replication quorum

Monitor ERROR: invalid value for number_sync_standbys: "2"
Monitor DETAIL: At least 3 standby nodes are required, and only 2 are currently participating in the replication quorum

number_sync_standbys 변경은 primary가 primary나 wait_primary 상태가 아니면 거부됩니다. candidate priority와 replication quorum 변경은 별도 함수가 처리합니다. primary가 apply_settings 상태이면 변경이 거부됩니다.

Monitor DETAIL: The primary node so must be in state "primary" or "wait_primary" to be able to apply configuration changes to its synchronous_standby_names setting
팁

v2.2 문서는 apply_settings를 쓰기 가능한 상태로 분류합니다. 상태는 read-write입니다. 그러나 새 synchronous_standby_names가 요구하는 응답을 받지 못하면 synchronous commit이 중단될 수 있습니다. 유효성 검사는 등록된 quorum 노드 수만 확인합니다. 현재 health까지 보장하지는 않습니다. 다만 synchronous_standby_names가 바뀌는 순간 commit이 기다리는 standby 집합도 달라집니다. 따라서 변경 직후 commit 지연을 한 번 확인합니다.

dropped​

pg_autoctl drop node는 노드를 즉시 삭제하지 않습니다. 먼저 dropped 목표를 지정합니다. keeper가 dropped에 도달했다고 보고하면 monitor가 노드 행을 삭제합니다. v1.6에서 추가된 상태입니다.

05:40:51 1602 INFO Removing node with name "node3" in formation "default" from the monitor
05:40:51 1602 INFO New state for this node (node 3, "node3") (node3:5432): dropped ➜ dropped
05:40:51 1602 INFO Node with id 3 in group 0 has been successfully dropped from the monitor

실측에서는 0.6초가 걸렸고 node3의 pg_autoctl은 종료되었습니다. dropped 전이는 로컬 PostgreSQL을 먼저 중지한 뒤 init 상태 파일을 삭제합니다. 등록만 해제할 목적으로 실행해도 해당 노드의 DB는 중지됩니다. 남은 quorum standby가 하나가 되자 number_sync_standbys는 1에서 0으로 자동 조정되었습니다. 노드가 이미 사라져 dropped를 보고할 수 없다면 --force로 monitor의 기록만 삭제합니다.

join_primary​

v2.2 문서의 상태 목록에는 join_primary가 남아 있습니다. 하지만 "더 이상 지정하지 않는다"고 명시되어 있습니다. 이전에는 새 standby가 합류할 때 primary가 HBA를 수정하는 동안 이 상태를 사용했습니다. 현재는 primary(또는 apply_settings)가 그 역할을 합니다. 오래된 글이나 로그에서 이 이름을 발견하면 v1.x 시절의 동작으로 이해하면 됩니다.

정리​

maintenance 경로는 대상이 마지막 quorum standby인지에 따라 달라집니다. secondary maintenance가 PostgreSQL을 중지하지 않는다는 점도 v2.2의 특징입니다. 설정 변경은 apply_settings로 primary에 적용됩니다. monitor는 안전성 검사로 위험한 조합을 차단합니다. 노드 삭제는 dropped를 거쳐 완료됩니다. 그 결과에 맞춰 number_sync_standbys도 조정됩니다.