본문으로 건너뛰기

5.3 Tablespaces

PostgreSQL의 tablespace는 특정 테이블·인덱스를 데이터 디렉토리 밖의 다른 위치에 저장하도록 하는 기능이다. 자주 조회되는 최근 데이터는 빠른 디스크에, 오래된 데이터는 값싼 디스크에 나눠 담는 식으로 스토리지 비용과 성능을 조율할 때 쓴다. 전통적으로는 서버에 심볼릭 링크를 걸고 CREATE TABLESPACE를 실행했지만, CloudNativePG에서는 Cluster 매니페스트에 선언하면 Operator가 tablespace마다 전용 PVC를 만들고 PostgreSQL에 등록까지 해 준다.

tablespace 선언

.spec.tablespaces에 이름과 스토리지만 나열하면 된다. 각 항목이 하나의 PVC로 프로비저닝된다.

spec:
  instances: 3
  tablespaces:
    - name: tbs1
      storage:
        size: 1Gi
    - name: tbs2
      storage:
        size: 2Gi
    - name: tbs3
      storage:
        size: 2Gi
    flowchart TD
    POD[PostgreSQL Pod] --> DATA[(PVC PGDATA)]
    POD --> WAL[(PVC walStorage)]
    POD --> T1[(PVC tbs1)]
    POD --> T2[(PVC tbs2)]
    T1 --> SC1[StorageClass 고속]
    T2 --> SC2[StorageClass 저비용]
  

tablespace마다 StorageClass와 크기를 다르게 줄 수 있다는 점이 핵심이다. 최근 데이터는 빠른 볼륨에, 연 단위 이력 데이터는 균형형 볼륨에 두는 구성을 그대로 선언한다.

tablespaces:
  - name: current
    storage:
      size: 100Gi
      storageClass: fastest
  - name: this_year
    storage:
      size: 500Gi
      storageClass: balanced

소유자 지정

tablespace는 기본적으로 app 사용자가 소유한다. 다른 role에 소유권을 주려면 owner를 명시한다.

tablespaces:
  - name: clapton
    owner:
      name: postgres
    storage:
      size: 1Gi
지정한 owner role이 존재하지 않으면 CNPG는 tablespace를 만들지 못하고, 그 사실을 클러스터 status에 보고한다. 소유자로 지정할 role은 미리 생성해 둔다.

임시 tablespace

정렬·해시 조인처럼 큰 중간 결과를 디스크에 흘리는 작업, 그리고 임시 테이블·인덱스를 별도 볼륨으로 몰아넣으려면 temporary: true로 표시한다. PostgreSQL의 temp_tablespaces에 등록되어 임시 객체가 이 볼륨에 생성된다.

tablespaces:
  - name: atablespace
    storage:
      size: 1Gi
    temporary: true

이 속성을 바꾸면 rolling update가 필요하지만 PostgreSQL 재시작까지는 필요하지 않다.

백업·복구 시 주의

tablespace는 별도 볼륨에 흩어져 있으므로 백업·복구 흐름에서 몇 가지 함정이 있다.

  • tablespace를 만든 직후 뜬 백업은 replica 기준으로 불완전할 수 있다.
  • tablespace를 추가하거나 제거한 뒤에는 새 base backup을 뜨기 전까지 WAL만으로 하는 복구가 실패한다.
  • 복구하는 클러스터는 원본과 정확히 같은 tablespace 정의 목록을 포함해야 한다.
    flowchart TD
    ADD[tablespace 추가·제거] --> WAL{새 base backup?}
    WAL -->|없음| FAIL[WAL 복구 실패]
    WAL -->|있음| OK[복구 정상]
  
tablespace 구성을 바꾼 직후에는 반드시 새 base backup을 확보한다. 그러지 않으면 그 시점 이후의 WAL 기반 복구(PITR 포함)가 실패할 수 있다.

Replica cluster

Replica cluster는 원본과 이름과 정의가 동일한 tablespace 목록을 가져야 한다. StorageClass와 크기는 달라도 되지만 이름 구성은 일치해야 한다.

spec:
  bootstrap:
    recovery:
      # 복구 방식 지정
  tablespaces:
    - name: tbs1
      storage:
        size: 1Gi
    - name: tbs2
      storage:
        size: 2Gi
현재 버전에서는 기존 CNPG 클러스터에서 tablespace를 제거할 수 없다. 제거 기능은 향후 릴리스에 예정되어 있으므로, 당장은 tablespace를 추가하는 방향으로만 설계한다.

다음 절에서는 이 Pod들을 어느 노드에 어떻게 배치할지 결정하는 scheduling을 다룬다.