18.4 로지컬 복제 기반 무중단 업그레이드
pg_upgrade --link도 수 분 다운타임 발생합니다. 메이저 업그레이드 다운타임을 초 단위까지 줄이려면 logical replication 기반 절차. 표준 무중단 업그레이드 흐름을 정리합니다.
큰 그림
flowchart LR
OLD["옛 17 primary<br/>(publisher)"]
NEW["새 18 cluster<br/>(subscriber)"]
APP["application"]
OLD -- "logical replication" --> NEW
APP -- "1. read·write 옛" --> OLD
APP -- "2. read·write 새 (cutover)" --> NEW
classDef old fill:#fed7aa,stroke:#c2410c,color:#7c2d12
classDef new fill:#d1fae5,stroke:#047857,color:#064e3b
classDef app fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
class OLD old
class NEW new
class APP app
표준 절차
1. 새 18 클러스터 준비 (initdb·설정)
2. 옛 클러스터의 스키마를 새 클러스터에 복원 (`pg_dump --schema-only`)
3. logical replication 활성 (publication + subscription)
4. 초기 sync 완료 대기 — 큰 DB는 수 시간
5. CDC 실시간 동기화 진행
6. 점검 시간 — application의 connection을 새 클러스터로 cut-over (분 단위)
7. 새 클러스터가 primary로 동작 검증
8. 옛 클러스터 _read-only_ 일정 기간 유지
9. 옛 클러스터 decommission1단계 — 새 클러스터 준비
# 새 18 클러스터 initdb
sudo -u postgres /usr/pgsql-18/bin/initdb -D /var/lib/pgsql/18/data \
--encoding=UTF8 --locale=C.UTF-8 --data-checksums
# wal_level·max_replication_slots 등 설정
cat << 'EOF' >> /var/lib/pgsql/18/data/postgresql.conf
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10
max_logical_replication_workers = 10
EOF
sudo systemctl start postgresql-182단계 — 스키마 복제
# 옛 (PG 17)에서 스키마만 dump
pg_dump --schema-only --no-publications --no-subscriptions \
-h old-pg -U postgres app_main > schema.sql
# 새 (PG 18)에 복원
psql -h new-pg -U postgres -d app_main -f schema.sql--schema-only로 데이터 없이 구조만. 새 클러스터의 스키마가 완벽히 동일해야 logical 시작합니다.
3단계 — publication·subscription
-- 옛 (publisher)
CREATE PUBLICATION pub_all FOR ALL TABLES;
-- 새 (subscriber)
CREATE SUBSCRIPTION sub_all
CONNECTION 'host=old-pg dbname=app_main user=repl_user password=secret'
PUBLICATION pub_all;CREATE SUBSCRIPTION이 자동으로 initial sync 시작합니다.
4단계 — 초기 sync 대기
-- 새 클러스터에서
SELECT subname, subenabled, subskiplsn,
(SELECT pg_size_pretty(pg_database_size(current_database())))
FROM pg_subscription;
SELECT subname, relname, srsubstate, srsublsn
FROM pg_subscription_rel sr
JOIN pg_subscription s ON sr.srsubid = s.oid
JOIN pg_class c ON sr.srrelid = c.oid
ORDER BY srsubstate;srsubstate | 의미 |
|---|---|
i | initial |
d | data being copied |
s | synced |
r | ready (streaming) |
모든 테이블이 r이 되면 CDC만 진행합니다. 큰 DB는 몇 시간 걸림.
5단계 — CDC 진행 확인
-- 옛에서
SELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS lag
FROM pg_replication_slots;
-- lag가 작은 상태 유지면 OK이 시점 옛 클러스터에 계속 트래픽, 새 클러스터는 뒤따라 적용합니다.
6단계 — application cutover
가장 중요한 단계. 다운타임 결정합니다.
1. application 쓰기를 옛에 잠시 차단 (read-only 또는 trickle)
2. 옛의 모든 변경이 새에 적용된 것 확인 (lag = 0)
3. 새 클러스터에서 sequence 갱신 — logical은 sequence 동기 안 됨
4. application connection string을 새 클러스터로 변경
5. 트래픽 시작sequence 동기화
-- 옛에서 모든 sequence 값
SELECT 'SELECT setval(''' || sequencename || ''', '
|| last_value || ');' AS cmd
FROM pg_sequences;새 클러스터에서 실행해 sequence 값 같게 설정합니다.
connection string 변경
| 방법 | 메모 |
|---|---|
| application 재배포 | 다운타임 짧음 |
| DNS record 변경 | TTL에 따라 |
| HAProxy 등 라우터 | 즉시 |
| pgBouncer 설정 변경 | 즉시 |
운영 권장: pgBouncer로 두 클러스터 동시에 정의해 두고 config switch.
7단계 — 검증
- 모든 application healthcheck
- 새 클러스터에서 writes 정상
- 옛 클러스터는 이제 read-only
-- 옛에서
ALTER DATABASE app_main SET default_transaction_read_only = on;
SELECT pg_reload_conf();8단계 — 정리
- 1~2주 옛 클러스터 유지 (롤백 대비)
- 충분히 안정 확인 후 decommission
-- 새 클러스터에서 subscription 제거
DROP SUBSCRIPTION sub_all;
-- 옛 클러스터의 publication 제거
DROP PUBLICATION pub_all;한계와 주의
logical replication의 한계(12.4)가 그대로 적용:
| 항목 | 메모 |
|---|---|
| sequence | 수동 갱신 필수 |
| DDL | 자동 동기 안 됨 — 마이그레이션 중 DDL 회피 |
| Large Object | 미지원 — bytea로 |
| 일부 테이블 미지원 | unlogged, temp, system catalog |
| replica identity | PK 또는 FULL 필수 (12.4) |
| application의 sequence 의존 | nextval 호출 시 새 클러스터에서 충돌 위험 |
확장 호환성
# 새 클러스터에도 같은 확장 설치
sudo dnf install -y pgvector_18 pg_partman_18-- 새 클러스터에서
CREATE EXTENSION pgvector;
CREATE EXTENSION pg_partman;
-- ...매니지드 클라우드
AWS RDS·Aurora·Azure Flexible Server 등 Blue/Green Deployment 기능이 자동화된 logical replication 업그레이드:
aws rds create-blue-green-deployment \
--source arn:aws:rds:...:db:mydb \
--target-engine-version 18.0매니지드가 자동 logical 셋업·sync·cutover를 제공합니다. 운영자 부담 ↓.
다운타임 추정
| 시나리오 | 다운타임 |
|---|---|
| application 재배포 | 30초~수 분 |
| pgBouncer config switch | < 10초 |
| DNS record + 짧은 TTL | < 1분 |
| HAProxy 자동 전환 | < 5초 |
CDC가 잘 따라잡으면 사용자 인지 불가 수준 가능합니다.
실패 시 롤백
cut-over 후 사고 발견하면:
- application connection을 옛 클러스터로 복원
- 새 클러스터에서 진행된 짧은 트래픽은 손실 (또는 reverse logical replication 시도 — 어려움)
- 사고 분석 후 재시도
옛 클러스터를 2주 이상 유지해야 안전합니다.
정리
- logical replication = 메이저 업그레이드 다운타임 초 단위 가능
- 절차: 스키마 dump → publication·subscription → initial sync → CDC → cut-over
- sequence는 수동 갱신, DDL은 업그레이드 중 회피
- pgBouncer 또는 HAProxy로 빠른 cut-over
- 매니지드 클라우드의 Blue/Green이 자동화 제공
- 옛 클러스터는 1~2주 유지로 롤백 대비
다음 절(18.5)에서는 월·분기 단위 작업인 — 마이너 업그레이드와 패치를 봅니다.