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임시 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[복구 정상]
Replica cluster
Replica cluster는 원본과 이름과 정의가 동일한 tablespace 목록을 가져야 한다. StorageClass와 크기는 달라도 되지만 이름 구성은 일치해야 한다.
spec:
bootstrap:
recovery:
# 복구 방식 지정
tablespaces:
- name: tbs1
storage:
size: 1Gi
- name: tbs2
storage:
size: 2Gi다음 절에서는 이 Pod들을 어느 노드에 어떻게 배치할지 결정하는 scheduling을 다룬다.