6.5 관리형 PostgreSQL 관점의 시사점
관리형 PostgreSQL 서비스는 대개 "인스턴스 하나에 볼륨 하나"를 단위로 삼습니다. 백업에는 볼륨 스냅샷이나 pgBackRest 같은 도구를 사용하고, 복제 인스턴스는 스냅샷에서 복원해 만듭니다. Neon은 이 단위를 해체했습니다. tenant 하나에 timeline 여러 개를 두고, compute는 필요에 따라 연결하거나 분리합니다. 이 장은 두 구조의 차이를 서비스 설계 관점에서 정리합니다. 또한 branching을 제공하려는 관리형 서비스가 CoW를 어느 계층에 둘지 선택할 때 따르는 대가를 비교합니다. 특정 회사의 구현이 아니라 공개된 제품 문서에서 확인되는 일반론만 다룹니다.
두 구조의 차이
| 관점 | 볼륨 기반 관리형 PostgreSQL | Neon 방식 |
|---|---|---|
| 데이터 단위 | 인스턴스별 블록 볼륨 | tenant의 layer 파일 (object storage) |
| 복제본 생성 | 스냅샷 복원, 크기 비례 시간 | timeline 메타데이터 추가, 크기 무관 |
| 과거 시점 | 백업 + WAL 재생 | history window 안 LSN 지정 |
| 유휴 비용 | 인스턴스 실행 시간 전체 | compute 정지 시 0, storage만 |
| 컴포넌트 수 | PostgreSQL + 백업 에이전트 | compute, safekeeper, pageserver, object storage, control plane |
| 엔진 | vanilla PostgreSQL | 패치된 PostgreSQL + 확장 |
볼륨 기반 구조에서 "개발용 복제본을 만들어 달라"는 요청은 스냅샷 복원 작업입니다. 소요 시간을 데이터 크기만으로 예측하기는 어렵습니다. 제품이 lazy loading을 지원하는지, 백업 형식이 물리인지 논리인지, 복원 후 재생할 WAL이 얼마나 되는지, compute와 스토리지 처리량이 얼마인지에 따라 갈립니다. PlanetScale의 PITR 문서도 data volume 외에 cluster 크기와 WAL replay 시간을 변수로 명시합니다. 따라서 도입 검토에서는 일반값을 인용하는 대신 자기 데이터로 한 번 복원해 측정합니다. 비용은 복제본 볼륨 전체와 인스턴스 실행 시간입니다. Neon 방식에서는 같은 요청이 API 호출 하나와 compute 기동으로 끝납니다. 비용은 delta와 실행 시간입니다. 사용자 경험의 차이는 큽니다. 그러나 서비스 제공자가 감당해야 하는 컴포넌트 수와 운영 복잡도도 그만큼 늘어납니다.
CoW를 어느 계층에 두는가
Branching을 제공하는 제품들은 copy-on-write를 서로 다른 계층에 구현했습니다. 계층 선택에 따라 생성 시간, PostgreSQL 호환성, 운영 부담이 함께 결정됩니다.
| 계층 | 대표 제품 | PostgreSQL 변경 | 인프라 요구 |
|---|---|---|---|
| 저장 엔진 교체 (page 버전 단위) | Neon, Lakebase | 패치 필요 | 자체 컴포넌트 4종 + object storage |
| 블록 스토리지 | Xata, Aurora, Tiger Cloud (Fluid Storage) | 없음 (vanilla) | CoW 지원 분산 블록 스토리지 |
| 파일 시스템 | DBLab (ZFS/LVM), 직접 구성 ZFS | 없음 (vanilla) | ZFS 또는 LVM thin, 단일 호스트 중심 |
| 데이터 구조 (테이블 버전) | Dolt, Doltgres | 별도 엔진 | 단일 바이너리 |
저장 엔진을 교체하면 branching과 scale to zero, autoscaling을 함께 얻습니다. object storage 기반의 저비용 이력 보존도 가능합니다. 대가는 PostgreSQL 패치를 major 버전마다 유지해야 한다는 점입니다. 확장 호환성을 검증해야 하고 WAL 포맷도 호환되지 않습니다. pageserver와 safekeeper라는 새 분산 시스템도 운영해야 합니다. Neon이 control plane을 비공개로 두고 있어 이 방식을 자체 서비스로 재현하려면 상당한 개발이 필요합니다.
블록 스토리지 계층에 CoW를 두면 PostgreSQL은 vanilla로 남고 확장 호환성 문제가 사라집니다. Xata는 OpenEBS Mayastor 기반 NVMe-oF 스토리지와 CloudNativePG 위에 branch operator를 구성했습니다. Aurora와 Tiger Cloud는 자체 스토리지 서비스가 이 역할을 합니다. CoW를 지원하는 분산 블록 스토리지를 운영하거나 구매해야 한다는 점이 대가입니다. 또한 branch마다 별도 PostgreSQL 인스턴스가 필요합니다. 따라서 scale to zero도 따로 구현해야 합니다. Aurora의 CoW clone 15개 제한이 이 계층의 구현 제약이 사용자에게 드러난 예입니다. Tiger Cloud도 마찬가지입니다. 공식 fork 문서는 free 서비스의 fork를 30~90초로 적고, standard 서비스는 backup 복원과 WAL 적용을 거치므로 시작까지 몇 분이 걸린다고만 설명합니다. 구체적인 상한은 문서에 없으므로 대상 서비스 크기에서 직접 측정합니다.
파일 시스템 계층은 도입이 가장 빠릅니다. PGDATA를 ZFS에 두고 스냅샷과 clone을 만들면 수 초 안에 thin clone이 생깁니다. DBLab은 이를 branch/commit 개념으로 표현합니다. 대가는 단일 호스트 중심이라는 점입니다. 원본과 clone이 같은 서버의 디스크와 CPU를 공유합니다. 따라서 운영 인스턴스에서 직접 clone을 만드는 대신 별도 복제 서버에서 만듭니다. 관리형 서비스로 제공하려면 이 복제 서버를 고객별로 운영하는 부담이 따릅니다.
제품별 용어 대응
같은 개념을 제품마다 다른 이름으로 부릅니다. 비교표를 읽을 때 혼동을 줄이기 위한 대응표입니다.
| 개념 | Neon | Aurora | Tiger Cloud | DBLab | Dolt | Supabase |
|---|---|---|---|---|---|---|
| CoW 복제본 | branch | clone | fork | clone (branch 위) | branch | branch (기본 스키마만, 데이터 포함 옵션) |
| 복제 원본 | parent branch | source cluster | parent service | snapshot | parent commit | main project |
| 과거 시점 | LSN, timestamp | latest restorable time | --to-timestamp | snapshot id | commit hash | 해당 없음 |
| 실행 단위 | compute endpoint | DB instance | service | clone (컨테이너) | sql-server | project |
| 되돌리기 | reset, restore | 해당 없음 | 해당 없음 | clone reset | checkout, reset | 해당 없음 |
"Branch"라는 단어가 Supabase에서는 스키마 복제 프로젝트를 가리킵니다. Dolt에서는 Git branch와 같은 데이터 버전을 뜻합니다. 제품을 비교할 때는 단어보다 표의 행을 기준으로 대조하는 편이 안전합니다.
고객 요구와 계층 매핑
관리형 서비스 사용자가 branching을 원하는 이유는 대개 다음 셋 중 하나입니다.
- 마이그레이션 리허설: 운영 데이터 크기에서 DDL 소요 시간과 lock 영향을 미리 확인
- 장애 재현: 특정 시각의 데이터 상태를 그대로 놓고 문제 쿼리를 재실행
- 분석용 복제: 운영에 부하를 주지 않고 무거운 쿼리를 실행
어느 계층이든 마이그레이션 리허설 요구를 충족합니다. 하지만 "운영과 같은 크기"가 중요하므로 데이터를 가져오지 않는 방식은 목적을 달성하지 못합니다. Supabase의 기본 branch는 schema와 마이그레이션만 옮깁니다. PlanetScale Postgres의 일반 새 branch는 schema도 데이터도 없는 빈 branch이고, backup이나 PITR에서 생성할 때만 둘 다 포함합니다. 두 제품에서 운영 크기의 리허설을 하려면 각각 include data 옵션이나 backup 기반 생성 경로를 써야 합니다. 장애 재현에는 과거 시점 지정이 필요합니다. 따라서 history를 보존하는 방식(Neon, Tiger fork의 --to-timestamp, DBLab의 스냅샷 보존)이 적합합니다. 분석용 복제는 read replica로 충족되는 경우가 많습니다. 쓰기가 필요한 분석(임시 테이블, 집계 테이블 생성)에만 branch가 필요합니다.
도입 시 확인할 사항
관리형 PostgreSQL을 운영하거나 도입을 검토하는 팀은 branching 기능을 평가할 때 다음을 순서대로 확인합니다.
먼저 데이터가 실제로 포함되는지 확인합니다. "branch"라는 이름을 쓰는 제품 중 절반은 스키마만 복사합니다. 다음으로 생성 시간이 데이터 크기에 비례하는지 확인합니다. 비례한다면 스냅샷 복원의 다른 이름입니다. 세 번째로 과거 시점 지정 여부와 그 범위(history window)에 따른 과금을 확인합니다. 네 번째로 branch에 붙는 compute의 최소 크기와 유휴 비용을 확인합니다. 마지막으로 branch의 변경을 운영으로 되돌려 넣는 경로가 있는지 확인합니다. Neon은 데이터 병합을 제공하지 않습니다. schema-diff와 마이그레이션 도구를 연계해 해결합니다. Dolt만 데이터 merge를 지원합니다.
자체 서비스에 branching을 추가하려는 경우에는 질문이 달라집니다. 먼저 기존 스토리지가 블록 수준 CoW를 지원하는지 확인합니다. 다음으로 PostgreSQL 패치를 유지할 조직 역량이 있는지 판단합니다. branch당 인스턴스를 실행하는 비용을 사용자에게 어떻게 청구할지도 정합니다. 마지막으로 history 보존과 백업 정책이 어떻게 겹치는지 검토합니다. 파일 시스템 계층에서 시작해 사용 패턴을 확인합니다. 이후 블록 스토리지 계층으로 옮기는 단계적 접근은 위험이 낮습니다.
History 보존과 백업 정책의 겹침
Neon의 history window는 백업 기능을 일부 대신합니다. Window 안의 논리적 장애는 branch나 restore로 복구합니다. 따라서 "매일 논리 백업을 받아 7일 보관"이라는 정책과 기능이 겹칩니다. 그러나 두 가지는 대체 관계가 아닙니다. History는 같은 pageserver와 object storage 안에 있습니다. 따라서 계정 삭제, 리전 장애, 서비스 종료 시 함께 사라집니다. 외부에 저장하는 pg_dump나 logical replication 기반 사본은 별도로 유지해야 합니다.
관리형 서비스 설계 관점에서는 history window 과금과 백업 보관 과금이 사용자에게 이중 부담으로 보이지 않도록 정리해야 합니다. Neon은 기본 history를 instant restore storage 항목으로 청구합니다. 여기에 더해 명시적으로 만드는 snapshot은 snapshot storage로 따로 계량되며 가격 문서 기준 $0.09/GB-month입니다. 기본 history 보존과 선택적 snapshot 백업이 별도 항목이라는 뜻입니다. 볼륨 스냅샷 기반 서비스는 스냅샷 보관만 과금하고 branch 기능은 없습니다. 두 방식을 함께 제공하려면 어느 쪽이 복구 정책의 정본인지 문서로 정해 둡니다.
실패 사례
볼륨 스냅샷 기반 "clone" 기능을 branching으로 소개했다고 가정합니다. 사용자가 PR마다 clone을 만들면 스토리지 비용이 선형으로 늘어납니다. 스냅샷은 생성 시점에 CoW 방식입니다. 그러나 복원된 볼륨은 전체 크기를 차지합니다. 따라서 branch 개수 × 데이터 크기로 비용이 커집니다. 사용 패턴이 "많이 만들고 짧게 쓴다"라면 계층을 다시 선택해야 합니다. "가끔 만들고 오래 쓴다"라면 스냅샷 복원으로도 충분합니다. 기능 이름보다 사용 패턴이 계층을 결정합니다.
연습 문제
- 현재 사용 중인 관리형 PostgreSQL의 복제본 생성 절차를 기록하고 100 GB 기준 소요 시간과 월 비용을 계산합니다.
- 위 표의 네 계층 중 우리 인프라에서 6개월 안에 구현 가능한 것을 골라 필요한 컴포넌트를 나열합니다.
- 팀의 최근 장애 사후 분석에서 "특정 시각의 데이터가 있었다면 원인을 빨리 찾았을" 사례가 있는지 찾습니다.
심화 체크
- 우리 사용자의 branch 사용 패턴(개수, 수명, 크기)을 추정할 근거가 있는가?
- 데이터 포함 여부와 생성 시간 비례 여부를 제품 데모 대신 문서와 측정으로 확인했는가?
- Branch에서 운영으로 변경을 반영하는 경로(schema diff, 마이그레이션 도구)를 함께 설계했는가?