본문으로 건너뛰기
4.2 기존 PostgreSQL 가져오기

4.2 기존 PostgreSQL 가져오기

이미 운영 중인 PostgreSQL을 CloudNativePG로 옮기고 싶을 때는 논리 백업(logical backup)으로 데이터를 가져올 수 있다. Operator가 원본에서 pg_dump로 데이터를 뽑아 새 클러스터에 pg_restore로 넣는 방식이다. 물리 복제인 pg_basebackup과 달리 major 버전이 달라도 되므로, 예를 들어 14.x에서 18.x로 올리면서 옮기는 major 업그레이드에도 쓸 수 있다.

import는 initdb bootstrap 안의 import 섹션으로 선언한다. 즉 새 클러스터를 initdb로 만든 직후, 원본에서 데이터를 끌어와 채우는 흐름이다.

    flowchart TD
  INITDB["initdb로 빈 클러스터"]
  DUMP["원본에서 pg_dump"]
  RESTORE["대상에 pg_restore"]
  ANALYZE["ANALYZE VERBOSE"]
  CLEAN["정리·설정 복원"]
  DONE["import 완료"]

  INITDB --> DUMP --> RESTORE --> ANALYZE --> CLEAN --> DONE
  

방식은 microservicemonolith 두 가지다.

microservice: 단일 DB 가져오기

microservice 방식은 원본의 데이터베이스 하나만 가져와, CloudNativePG가 권장하는 “클러스터 하나에 DB 하나” 구조에 맞춘다.

  • 원본 DB 하나만 대상으로 지정 (여러 개 불가)
  • 가져온 DB와 소유자는 대상 설정 이름(기본 app)으로 바뀐다
  • role은 가져오지 않는다
  • import 후 postImportApplicationSQL로 커스텀 SQL 실행 가능
  • 가져온 DB에 ANALYZE VERBOSE 자동 실행
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-microservice
spec:
  instances: 3
  bootstrap:
    initdb:
      import:
        type: microservice
        databases:
          - angus
        source:
          externalCluster: cluster-pg96
  storage:
    size: 1Gi
  externalClusters:
    - name: cluster-pg96
      connectionParameters:
        host: pg96.local
        user: postgres
        dbname: postgres
      password:
        name: cluster-pg96-superuser
        key: password

위 예는 원본(cluster-pg96)의 angus DB를 가져와 새 클러스터의 애플리케이션 DB로 만든다. 원본 접속 정보는 externalClusters에 정의하고 source.externalCluster로 참조한다.

monolith: 여러 DB·role 가져오기

monolith 방식은 여러 데이터베이스와 여러 role을 한 번에 가져오며, 원본 구조를 그대로 보존한다.

  • 여러 데이터베이스와 role을 함께 가져온다
  • DB 이름과 소유자를 원본 그대로 유지한다
  • role도 가져오되 제약이 있다 — postgres·streaming_replica·cnpg_pooler_pgbouncer는 제외되고, SUPERUSER 옵션은 제거된다
  • 와일드카드 "*"로 모든 DB·role을 지정할 수 있다
  • 각 DB에 ANALYZE VERBOSE 자동 실행
  • postImportApplicationSQL지원하지 않는다
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-monolith
spec:
  instances: 3
  bootstrap:
    initdb:
      import:
        type: monolith
        databases:
          - accounting
          - banking
          - resort
        roles:
          - accountant
          - bank_user
        source:
          externalCluster: cluster-pg96
  storage:
    size: 1Gi
  externalClusters:
    - name: cluster-pg96
      connectionParameters:
        host: pg96.local
        user: postgres
        dbname: postgres
        sslmode: require
      password:
        name: cluster-pg96-superuser
        key: password
microservice는 DB를 반드시 하나만, monolith는 최소 하나 이상을 지정해야 한다. 애플리케이션을 여러 DB로 쪼개 각각 별도 클러스터로 운영하는 CloudNativePG의 지향점에는 microservice가 맞고, 기존 통합 DB를 그대로 옮겨야 할 때는 monolith가 맞다.

요구 조건

  • import 진행 중 원본 클러스터가 쿠버네티스에서 접근 가능해야 한다 (트래픽 명시적 허용 필요)
  • 접속 유저는 superuser이거나 pg_dump에 준하는 권한을 가져야 한다
  • 임시 dump 파일과 복원 데이터를 담을 PGDATA 볼륨 여유 공간이 있어야 한다
  • 대상의 pg_dump 버전이 원본 버전 이상이어야 한다

성능 튜닝

import 동안 CloudNativePG는 속도를 위해 PostgreSQL 설정을 일시적으로 조정한다. archive_mode: off, fsync: off, full_page_writes: off, max_wal_senders: 0, wal_level: minimal로 바꾼 뒤, 완료 후 원래대로 되돌리고 initdb --sync-only로 durability를 확보한다.

추가로 pg_dump·pg_restore에 넘길 옵션을 직접 지정해 성능을 끌어올릴 수 있다.

bootstrap:
  initdb:
    import:
      type: microservice
      databases:
        - app
      source:
        externalCluster: cluster-example
      pgDumpExtraOptions:
        - '--jobs=2'
      pgRestoreExtraOptions:
        - '--jobs=2'

복원 단계별로 병렬도를 다르게 주려면 단계별 옵션을 쓴다. 단계별 옵션이 있으면 일반 pgRestoreExtraOptions보다 우선한다.

bootstrap:
  initdb:
    import:
      type: microservice
      databases:
        - mynewdb
      source:
        externalCluster: sourcedb-external
      pgRestorePredataOptions:
        - '--jobs=1'
      pgRestoreDataOptions:
        - '--jobs=4'
      pgRestorePostdataOptions:
        - '--jobs=2'
import는 “오프라인"이다. 백업이 시작된 뒤 원본에 들어온 쓰기는 대상에 반영되지 않으므로, 정합성이 필요하면 원본 쓰기를 멈추고 진행한다. 또한 pg_dump·pg_restore 옵션은 Operator가 검증하지 않고 그대로 전달하므로, 호환되지 않는 플래그는 import를 망가뜨릴 수 있다.

정리

  • 기존 PostgreSQL은 initdb.import로 논리 백업(pg_dump/pg_restore)해 가져온다 — major 버전이 달라도 가능
  • microservice: 단일 DB, 이름을 app으로 변경, role 미포함, postImportApplicationSQL 지원
  • monolith: 다중 DB·role, 이름 보존, superuser·예약 role 제외
  • 원본 접속은 externalClusters에 정의하고 source.externalCluster로 참조
  • import는 오프라인이므로 정합성이 필요하면 원본 쓰기 중단 후 진행

다음 절(4.3)에서는 클러스터를 구성하는 인스턴스 Pod를 세밀하게 조정하는 방법을 본다.