6.7 업그레이드
pg_auto_failover 환경의 업그레이드는 세 종류입니다. pg_auto_failover 자체, PostgreSQL minor 버전, PostgreSQL major 버전을 올리는 경우입니다. 첫 번째 절차는 v2.2 운영 문서에 나와 있습니다. 순서를 지키지 않으면 서비스가 중단될 수 있습니다. 두 번째는 maintenance와 switchover를 조합하면 됩니다. 세 번째는 pg_auto_failover가 자동화하지 않습니다. 이 장의 절차는 모두 문서를 기반으로 작성했습니다. 이 노트의 실습 환경에서는 수행하지 않았습니다.
pg_auto_failover 업그레이드 (1.4 이후)
monitor와 데이터 노드는 역할이 다르므로 업그레이드 방식도 다릅니다. monitor에서는 pgautofailover extension의 스키마가 바뀔 수 있습니다. 따라서 ALTER EXTENSION pgautofailover UPDATE가 필요합니다. 데이터 노드의 keeper는 monitor에 접속할 때마다 extension 버전을 확인합니다. 예상한 버전이 아니면 node-active 하위 프로세스를 종료합니다. 그러면 상위 pg_autoctl 프로세스가 디스크의 바이너리로 하위 프로세스를 다시 실행합니다.
따라서 다음 순서대로 진행해야 합니다.
- 모든 데이터 노드와 monitor에 새 패키지를 설치합니다. 이 단계에서는 어떤 프로세스도 재시작하지 않습니다.
- monitor 서비스를 재시작합니다(
sudo systemctl restart pgautofailover). 로그에서ALTER EXTENSION pgautofailover UPDATE TO ...가 실행되었는지 확인합니다. - 데이터 노드는 자동으로 새 바이너리의 node-active 프로세스로 전환됩니다.
pg_autoctl show state로 모든 노드의 상태를 확인합니다.
monitor가 재시작되는 동안에는 failover가 일어날 수 없습니다. 노드는 monitor 접속 실패를 로그에 남기고 접속을 재시도합니다. PostgreSQL 서비스 자체는 계속 실행됩니다.
데이터 노드에 새 패키지를 설치하기 전에 monitor를 먼저 업그레이드하면 안 됩니다. 문서에 따르면 keeper는 버전이 일치하지 않으면 node-active 프로세스를 재시작합니다. 그러나 디스크에는 여전히 이전 바이너리가 있으므로 버전 불일치가 반복됩니다. 재시작을 5번 반복하면 pg_autoctl은 재시도를 중단하고 종료합니다. 이때 로컬 PostgreSQL도 함께 중단됩니다. 모든 노드가 동시에 이 상태가 되면 서비스가 중단됩니다.
Debian 계열에서는 패키지 이름에 버전이 포함되던 시기가 있었습니다. 문서에는 1.4에서 1.5로 올리는 다음 예시가 나와 있습니다.
sudo apt-get remove pg-auto-failover-cli-1.4 postgresql-11-auto-failover-1.4
sudo apt-get install -q -y pg-auto-failover-cli-1.5 postgresql-11-auto-failover-1.5
현재 PGDG 패키지 이름은 pg-auto-failover-cli, postgresql-17-auto-failover처럼 버전이 없는 형태입니다(4.1).
1.3 이하에서 올리는 경우
1.3 이하는 온라인 전환을 지원하지 않습니다. 따라서 모든 pg_autoctl 프로세스를 재시작해야 합니다. 문서는 failover가 개입하지 않도록 다음 순서로 진행하라고 안내합니다. secondary를 먼저 maintenance로 전환한 뒤 패키지를 설치합니다. 이어서 monitor와 모든 노드를 재시작하고 maintenance를 해제합니다.
btree_gist 의존성
1.4.0부터 extension은 contrib의 btree_gist를 요구합니다. 일부 릴리스에는 이 의존성을 생성하는 과정에 버그가 있습니다. monitor 업그레이드가 실패하면 monitor 데이터베이스에서 직접 생성하라고 문서에서 안내합니다.
-- monitor의 pg_auto_failover 데이터베이스에서
create extension btree_gist;
main 브랜치의 extension 2.3은 ltree도 요구합니다(pgautofailover.control의 requires = 'btree_gist, ltree'). 다음 릴리스로 올리기 전에는 monitor 서버에 contrib 패키지가 있는지 확인합니다.
PostgreSQL minor 업그레이드
minor 업그레이드는 바이너리를 교체하고 재시작하면 완료됩니다. 물리 복제 호환성도 유지됩니다. pg_auto_failover에서는 PostgreSQL이 keeper의 자식 프로세스로 실행됩니다. 따라서 PostgreSQL만 별도로 재시작하지 말고 keeper 서비스 단위로 관리합니다. 권장 절차는 다음과 같습니다.
- 모든 노드에 새 PostgreSQL 패키지를 설치합니다.
- secondary에서
pg_autoctl enable maintenance후 서비스를 재시작하고disable maintenance로 복귀시킵니다. standby가 여럿이면 하나씩 반복합니다. pg_autoctl perform switchover로 업그레이드된 노드를 primary로 만듭니다.- 옛 primary(이제 secondary)에서 2번을 반복합니다.
switchover 한 번에 발생한 쓰기 공백은 실습에서 1.35초였습니다(6.2).
PostgreSQL major 업그레이드
PostgreSQL의 물리 streaming replication은 major 버전이 같은 서버끼리만 동작합니다. 따라서 노드를 하나씩 올리는 rolling 방식은 사용할 수 없습니다. pg_auto_failover v2.2 문서에도 major 업그레이드 절차가 없습니다. 선택할 수 있는 방법은 도구에서 지원하지 않는 별도 절차뿐입니다.
- 새 major 버전으로 별도 formation(또는 별도 monitor와 클러스터)을 만들고 logical replication으로 데이터를 옮긴 뒤 애플리케이션 연결을 전환
- 중단 시간을 받아들이고 primary에서
pg_upgrade를 실행한 뒤, standby는 drop 후 새로 추가해 pg_basebackup으로 재구축
두 번째 방식에서 monitor와 keeper를 유지한 채 primary만 중단하면 monitor는 이를 장애로 판단합니다. 그러면 standby를 승격합니다. primary를 중단하기 전에 standby를 drop하거나 maintenance로 전환해야 합니다. 이렇게 승격 후보를 제거해야 합니다. 이 방식은 pg_upgrade 동안 서비스가 중단됩니다. standby를 재구축하는 동안에는 동기 복제 이중화가 제공되지 않습니다. 어느 방식을 선택하든 monitor의 노드 레코드와 slot을 정리해야 합니다. 이 노트에서는 두 방식 모두 실습하지 않았습니다.
README는 monitor용 extension 패키지가 "monitor 자신이 실행할 PostgreSQL 버전"에 따라 정해진다고 설명합니다. monitor는 복제에 참여하지 않으며 SQL로만 노드와 통신합니다. 다만 monitor와 데이터 노드의 major 버전이 다른 구성은 이 노트에서 검증하지 않았습니다.
정리
pg_auto_failover는 모든 노드에 패키지를 먼저 설치해야 합니다. 그다음 monitor를 마지막에 재시작하는 것이 업그레이드의 핵심입니다. PostgreSQL minor는 maintenance와 switchover를 조합해 중단 시간을 최소화합니다. major는 도구가 지원하지 않습니다. 따라서 logical replication을 이용한 이전이나 서비스 중단을 동반한 재구축을 설계해야 합니다.