본문으로 건너뛰기
8.3 쓰기 연산

8.3 쓰기 연산

GET 계열이 상태를 읽기만 한다면, PUT, POST, PATCH, DELETE 계열은 노드와 클러스터의 상태를 바꾼다. 공식 문서는 이들을 unsafe 엔드포인트로 분류한다. patronictl의 멤버 조작 명령 상당수가 내부적으로 이 엔드포인트를 호출하므로(Part VII), 여기서 정리하는 계약은 patronictl 동작의 계약이기도 하다.

dynamic configuration 갱신: PATCH와 PUT

PATCH /config는 body에 담긴 키만 부분 갱신하고, 갱신이 반영된 전체 설정을 반환한다.

curl -s -XPATCH -d \
  '{"loop_wait": 5, "ttl": 20, "postgresql": {"parameters": {"max_connections": "101"}}}' \
  http://127.0.0.1:8008/config

파라미터를 지우고 싶으면 값에 null을 지정한다.

curl -s -XPATCH -d \
  '{"postgresql": {"parameters": {"max_connections": null}}}' \
  http://127.0.0.1:8008/config

PUT /config는 기존 dynamic configuration을 조건 없이 통째로 덮어쓴다.

PUT은 body에 없는 키를 남기지 않는다. 일부만 고칠 생각으로 PUT을 보내면 나머지 설정이 사라진다. 일상적인 변경은 PATCH /config 또는 patronictl edit-config로 하고, PUT은 설정 전체를 의도적으로 교체할 때만 쓴다.

switchover와 failover

POST /switchover는 body에 leader가 필수이고 candidate, scheduled_at은 선택이다. leader가 존재하는 정상 클러스터에서만 동작한다.

curl -s -XPOST -d '{"leader": "patroni1", "candidate": "patroni2"}' \
  http://127.0.0.1:8008/switchover

scheduled_at에 timezone을 포함한 timestamp를 넣으면 예약 switchover가 되고, 예약 삭제는 DELETE /switchover다.

curl -s -XPOST -d '{"leader": "patroni1", "scheduled_at": "2026-08-05T02:00:00+09:00"}' \
  http://127.0.0.1:8008/switchover
curl -s -XDELETE http://127.0.0.1:8008/switchover

POST /failover는 body에 candidate가 필수이며, leader가 없는 클러스터에서도 동작한다. body에 leader를 함께 넣으면 switchover로 처리된다. 두 연산의 후보 선정 기준과 진행 순서는 Part VI에서 다룬다.

4.0.0부터 /switchover, /failover, /restart 요청의 role 값으로 master를 받지 않는다. primary를 쓴다.

응답 코드 체계

쓰기 연산의 응답은 다섯 코드로 정리된다.

코드의미
200요청이 즉시 수행 완료됨
202예약 접수됨 (scheduled_at, schedule 지정 시)
400요청 형식이나 값이 잘못됨
412전제조건 불충족, 상세 사유를 body로 반환
503수행 실패

switchover 요청 하나를 따라가면 흐름이 잡힌다.

    flowchart TD
  REQ["POST /switchover"] --> VAL{"body와 전제조건 검증"}
  VAL -->|형식 오류| C400["400 반환"]
  VAL -->|전제조건 불충족| C412["412 반환"]
  VAL -->|통과| SCHED{"scheduled_at 지정?"}
  SCHED -->|예| C202["202 예약 접수"]
  SCHED -->|아니오| RUN["switchover 실행"]
  RUN -->|성공| C200["200 반환"]
  RUN -->|실패| C503["503 반환"]
  

노드 단위 연산

POST /restart 와 DELETE /restart

요청을 받은 노드의 PostgreSQL을 재시작한다. body 없이 호출하면 즉시 재시작하고, 다섯 가지 선택 필드로 조건을 건다.

필드의미
restart_pendingtrue면 pending restart 플래그가 있을 때만 재시작
role노드가 지정 role일 때만 재시작
postgres_version현재 PostgreSQL 버전이 지정값보다 낮을 때만 재시작
timeout재시작 시 primary_start_timeout 값을 오버라이드
scheduletimezone 포함 timestamp로 예약 재시작
curl -s -XPOST -d '{"restart_pending": true, "timeout": 120}' \
  http://127.0.0.1:8008/restart
curl -s -XDELETE http://127.0.0.1:8008/restart   # 예약된 restart 취소

restart_pendingpostgres_version은 rolling restart를 스크립트로 조립할 때 유용하다. 조건이 맞지 않는 노드에서는 재시작이 일어나지 않으므로, 전체 멤버에 같은 요청을 보내도 필요한 노드만 재시작된다.

POST /reload

로컬 설정 파일을 다시 읽어 적용한다. SIGHUP에 해당하는 동작이라 PostgreSQL을 재시작하지 않으며, 재시작이 필요한 파라미터는 pending restart로 남아 별도의 restart를 기다린다.

curl -s -XPOST http://127.0.0.1:8008/reload

POST /reinitialize

해당 노드의 데이터 디렉토리를 재초기화한다. replica에서만 실행이 허용된다. 데이터 디렉토리를 제거한 뒤 pg_basebackup 또는 구성된 대체 replica 생성 방법(create_replica_methods, Part V 참고)을 실행해 처음부터 다시 받는다.

body는 선택이다. {"force": true}는 이미 recovery 동작이 돌고 있는 노드에서 loop를 끊고 재초기화를 강제할 때 쓰고, {"from-leader": true}는 basebackup을 leader에서 직접 뜨도록 지정한다.

curl -s -XPOST -d '{"from-leader": true}' http://127.0.0.1:8008/reinitialize
reinitialize는 데이터 디렉토리를 삭제하는 파괴적 연산이다. primary에서는 거부된다는 안전장치가 있지만, 재복제가 끝날 때까지 해당 replica는 읽기 pool에서 빠지므로 대상 노드와 클러스터의 읽기 여유를 확인한 뒤 실행한다.

정리

  • /config는 PATCH가 부분 갱신, PUT이 전체 덮어쓰기다. 파라미터 삭제는 null 값으로 한다.
  • /switchoverleader가, /failovercandidate가 필수다. 예약된 연산은 202로 접수되고 DELETE로 취소한다.
  • /restart, /reload, /reinitialize는 요청을 받은 노드에만 작용하며, reinitialize는 replica 전용의 파괴적 연산이다.