본문으로 건너뛰기

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

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

temporary tablespace를 나중에 추가하면 rolling update가 필요합니다. 반면 기존 tablespace의 temporary 값만 바꾸는 것은 temp_tablespaces 목록에 이름을 넣거나 빼는 동작이라 PostgreSQL 재시작이 필요하지 않습니다.

백업·복구 시 주의​

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

  • tablespace를 만든 직후 뜬 백업은 replica 기준으로 불완전할 수 있습니다.
  • tablespace를 추가하거나 제거한 뒤에는 새 base backup을 뜨기 전까지 WAL만으로 하는 복구가 실패합니다.
  • 복구하는 클러스터는 원본과 정확히 같은 tablespace 정의 목록을 포함해야 합니다.
노트

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를 추가하는 방향으로만 설계합니다.