PostgreSQL

PostgreSQL: pg_upgrade

dewstream 2025. 8. 6. 08:00
728x90

※ PostgreSQL: pg_upgrade.

 

안녕하세요. 듀스트림입니다.

 

오늘 포스팅은 PostgreSQL 버전 업그레이드 시, 사용하는 도구인 pg_upgrade에 대한 내용입니다.


1. pg_upgrade?

pg_upgrade는 데이터 파일을 그대로 재사용하면서 시스템 카탈로그만 New 버전 형식으로 재생성합니다.

(귀찮은 대규모 덤프/복원을 대체할 수 있습니다.)

 

▸ 제약사항

  • PostgreSQL 9.2 버전 이상에서만 지원.
  • TO-BE 버전의 PostgreSQL이 설치되어 있어야 함.
  • pg_upgrade는 TO-BE 버전의 바이너리에서 수행해야 함.
  • 바이너리가 호환 가능해야 함. (예: 64bit ↔ 64bit)
  • AS-IS와 TO-BE의 컴파일 옵션이 동일해야 함. (--with-blocksize, --with-wal-segsize 등)
  • shared_preload_libraries에 등록된 Extension은 TO-BE 경로에 재컴파일 필요.
  • --copy로 진행 시 디스크 용량 2배 필요.

 

+ 컴파일 옵션 확인 방법

pg_config --configure

▸ 원리

  1. 새 17 클러스터에 initdb 수행.
  2. 두 클러스터를 임시 포트로 기동.
  3. OID / filenode 매핑 테이블 작성 → 시스템 카탈로그 재작성.
  4. 사용자 테이블, 인덱스 파일은 Hard Link(-k)·Copy(Default)·Clone 중 선택한 방식으로 이동/공유.
  5. 필요 시 REINDEX/CLUSTER 스크립트, 통계 재수집 스크립트를 자동 출력.

▸ 옵션

옵션 의미 설명 활용도
--clone COW (reflink) 복제 Btrfs/XFS/APFS 환경에서 속도·공간 이득 링크 장점 + 롤백 용이
--jobs=N 병렬 스레드 수 -j 8 로 대형 테이블스페이스 복사 속도 측정 I/O 다중화
--no-sync fsync 생략 장애 발생 시 손상 가능성 주의 테스트 전용
--retain 로그·SQL 보존 성공 후도 분석 가능 자동화 시 디버그
--sync-method=syncfs 리눅스 syncfs 시스템콜 많은 파일을 가진 대형 클러스터에서 시간 절약 대규모 환경
--socketdir=/tmp/pgup 소켓 경로 지정 긴 PWD 문제로 소켓 생성 실패 예방 컨테이너·CI

 

+ --copy vs --clone

  • --copy가 제일 안전합니다.
항목 --copy (Default) --clone
작동 방식 데이터 파일을 바이트 단위로 완전 복사 파일 시스템의 Copy-On-Write (reflink) 기능으로 즉시 “복제”
지원 환경 모든 OS/파일시스템에서 동작 Linux 4.5+의 Btrfs·XFS( reflink 모드) 및 macOS APFS 등 COW 지원 FS 한정
처리 속도 데이터 크기만큼 I/O → 느림 하드 링크급 매우 빠름 (실제 I/O 거의 없음)
초기 디스크 사용량 2 배 필요 (원본 + 사본) 거의 0 증가 (변경 시점에만 블록 분리)
Old 클러스터 안전성 완전 격리 → 언제든 롤백 가능 복제 후에도 원본은 변경되지 않으므로 롤백 가능
실패 조건 없음 (항상 가능) FS가 reflink 미지원이면 pg_upgrade가 에러 후 중단
추가 고려 사항 대형 클러스터는 시간·공간 부담 업그레이드 후 쓰기량만큼 디스크가 점진적으로 증가
지원되지 않는 파일시스템에서는 오류 반환


▸ 업그레이드 전 체크리스트

구분 필수 이유
호환 아키텍처 64-bit↔64-bit, endian 동일 저장 형식 차이 방지
shared_preload_libraries 버전에 맞는 Extension 재컴파일 바이너리 ABI
contrib 모듈 버전 pgcrypto, ltree 등 카탈로그 구조 변경
필수 확장 pg_upgrade --check가 검출 DROP 후 RESTORE 가능
파라미터 변경 버전에 맞게 파라미터명과 설정 방식 변경 기동 오류 예방
※ TO-BE 클러스터에는 반드시 "template0, template1, postgres" 3개의 데이터베이스만 존재해야 합니다.
→ 다른 작업을 하셨다면 TO-BE의 PGDATA 영역을 클리어 후 initdb 하시는 게 제일 편합니다.

2. 테스트

▸ 테스트 모드

  • 실제 파일 변경 없이 필수 Extension, 파라미터, ABI를 검사합니다.
pg_upgrade --check -b <OLD_PGBIN> -B <NEW_PGBIN> -d <OLD_PGDATA> -D <NEW_PGBIN>


▸ 수행

pg_upgrade -j <N> -b <OLD_PGBIN> -B <NEW_PGBIN> -d <OLD_PGDATA> -D <NEW_PGBIN>

.

.

.


▸ 업그레이드 후 통계 재수집

vacuumdb --all --analyze-in-stages --jobs=<N>

이후,

  • Extension 재설치 또는 업그레이드 (ALTER EXTENSION … UPDATE TO ...).
  • 필요시 REINDEX.
  • APP 테스트.
  • OLD 클러스터 삭제 (pg_upgrade를 수행한 경로에 delete_old_cluster.sh이 생성되어 있음).

오늘은 여기까지 ~

 

728x90