본문으로 건너뛰기
1.2 인스턴스와 클러스터

1.2 인스턴스와 클러스터

PostgreSQL의 인스턴스(instance) 한 개는 postmaster 프로세스 한 개 + 데이터 디렉토리(PGDATA) 한 개의 조합입니다. PostgreSQL 공식 문서는 이 단위를 데이터베이스 클러스터(database cluster)라고 부릅니다. 한 클러스터 안에는 여러 데이터베이스가 들어가지만, 클라이언트 연결은 항상 그 중 하나의 데이터베이스로만 들어갑니다.

운영자가 자주 혼동하는 지점은 “클러스터” 단어입니다. PostgreSQL의 “데이터베이스 클러스터"는 분산 시스템에서 말하는 “여러 노드로 묶인 클러스터"와는 다른 개념입니다. 본 절에서는 우선 단일 인스턴스 관점에서 클러스터·데이터베이스·스키마·객체의 계층 관계를 정리하고, PGDATA의 내부 구조를 봅니다.

계층 관계

    flowchart TD
  C["<b>Cluster</b><br/>postmaster 1개<br/>PGDATA 1개"]
  C --> DB1["Database: <b>postgres</b><br/>(관리·기본)"]
  C --> DB2["Database: <b>template1</b><br/>(새 DB 템플릿)"]
  C --> DB3["Database: <b>template0</b><br/>(백업 템플릿)"]
  C --> DB4["Database: <b>app_main</b>"]
  DB4 --> S1["Schema: public"]
  DB4 --> S2["Schema: billing"]
  S1 --> T1["Table · Index · Sequence …"]
  S2 --> T2["Table · Index · Sequence …"]

  classDef cluster fill:#ede9fe,stroke:#6d28d9,color:#3b0764,stroke-width:2px
  classDef db fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
  classDef sch fill:#d1fae5,stroke:#047857,color:#064e3b
  classDef obj fill:#fef3c7,stroke:#b45309,color:#78350f
  class C cluster
  class DB1,DB2,DB3,DB4 db
  class S1,S2 sch
  class T1,T2 obj
  

공식 문서가 정의하는 전체 계층은 cluster → database → schema → table(또는 다른 객체) 다. 이 네 레벨이 PostgreSQL의 네임스페이스 골격입니다.

레벨단위메모
Clusterpostmaster 1개가 관리하는 데이터베이스 묶음initdb로 생성, 파일시스템상 PGDATA 디렉토리 1개
Database같은 클러스터 안에서 격리된 단위CREATE DATABASE, 클러스터 안 PostgreSQL OID로 식별
Schema데이터베이스 안의 네임스페이스CREATE SCHEMA, 이름 공간·권한 분리
객체테이블·인덱스·시퀀스·뷰·함수 등항상 스키마 안에 속함

한 연결 = 한 데이터베이스

클라이언트는 접속할 때 반드시 데이터베이스 하나를 골라야 합니다.

psql -h localhost -U postgres -d app_main

같은 클러스터 안에 있어도 다른 데이터베이스의 테이블을 직접 join하는 건 불가능합니다. 이건 PostgreSQL의 의도된 격리 모델입니다.

공식 문서 인용: “When connecting to the database server, a client must specify the database name in its connection request. It is not possible to access more than one database per connection.”

다른 데이터베이스에 접근하려면 두 가지 우회 경로가 있습니다.

우회방법비고
postgres_fdw다른 DB(같은 클러스터든 다른 클러스터든)를 외부 테이블로 매핑표준 SQL/MED, Part XVI 참고
dblink 확장함수 호출로 다른 DB 쿼리조인 자체는 불가능, 결과 returning

자동 생성되는 세 데이터베이스

initdb가 클러스터를 초기화하면 데이터베이스 세 개가 미리 들어갑니다.

데이터베이스역할
postgres관리용·기본 접속 데이터베이스. 유틸리티·서드파티 도구가 디폴트로 쓴다
template1새 데이터베이스(CREATE DATABASE foo) 생성 시 복제되는 템플릿. 여기 객체를 만들어 두면 이후 만든 모든 DB에 자동으로 들어간다
template0원본 백업 템플릿. 절대 수정하지 않는다. pg_dump·복구 시 깨끗한 베이스로 사용

데이터 디렉토리 (PGDATA)

클러스터 한 개는 파일시스템상 하나의 디렉토리다. 이 디렉토리를 PGDATA라 부르며, 환경 변수 PGDATA 또는 pg_ctl -D 옵션으로 위치를 지정합니다.

흔히 쓰이는 경로:

OS·배포기본 PGDATA
RHEL/Rocky (PGDG yum)/var/lib/pgsql/<version>/data
Debian/Ubuntu (PGDG apt)/var/lib/postgresql/<version>/<cluster>
Homebrew macOS/opt/homebrew/var/postgresql@<version>
소스 빌드 관례/usr/local/pgsql/data
공식 Docker 이미지/var/lib/postgresql/data

PGDATA 내부 구조

$PGDATA/
├── PG_VERSION                # 메이저 버전 (예: "17")
├── postgresql.conf           # 주 설정
├── pg_hba.conf               # 클라이언트 인증
├── pg_ident.conf             # OS 사용자 ↔ DB 사용자 매핑
├── postgresql.auto.conf      # ALTER SYSTEM이 쓰는 설정
├── postmaster.pid            # 실행 중인 postmaster PID·소켓·포트 정보
├── postmaster.opts           # 마지막 기동 명령행 옵션
├── base/                     # 데이터베이스별 데이터 (DB OID로 디렉토리)
│   ├── 1/                    # template1
│   ├── 4/                    # template0
│   ├── 5/                    # postgres
│   └── 16384/                # 사용자 DB (CREATE DATABASE 결과)
├── global/                   # 클러스터 전역 카탈로그 (pg_database 등)
├── pg_wal/                   # WAL 세그먼트 (16MB 단위 파일)
├── pg_tblspc/                # tablespace 심볼릭 링크
├── pg_xact/                  # 트랜잭션 커밋 상태 (CLOG)
├── pg_multixact/             # 멀티트랜잭션 (공유 row lock)
├── pg_subtrans/              # 서브트랜잭션 상태
├── pg_commit_ts/             # 커밋 타임스탬프
├── pg_twophase/              # 2PC prepared transaction 상태
├── pg_replslot/              # 복제 슬롯
├── pg_logical/               # 로지컬 디코딩 상태
├── pg_serial/                # SERIALIZABLE 트랜잭션 정보
├── pg_notify/                # LISTEN/NOTIFY 큐
├── pg_snapshots/             # 내보낸 스냅샷
├── pg_stat/                  # 통계 시스템 영구 파일
├── pg_stat_tmp/              # 통계 시스템 임시 파일
└── pg_dynshmem/              # 동적 공유 메모리 메타데이터

각 항목의 역할을 묶어서 봅니다.

그룹디렉토리·파일용도
메타PG_VERSION, postmaster.pid, postmaster.opts버전·기동 상태 표시
설정postgresql.conf, pg_hba.conf, pg_ident.conf, postgresql.auto.conf서버·인증·매핑·동적 설정
실제 데이터base/, global/, pg_tblspc/사용자 데이터 + 전역 카탈로그 + 외부 tablespace 링크
WALpg_wal/트랜잭션 로그 (16MB 세그먼트, archive·replication의 원천)
트랜잭션 상태pg_xact/, pg_multixact/, pg_subtrans/, pg_commit_ts/, pg_twophase/커밋·잠금·서브·2PC 상태
복제·로지컬pg_replslot/, pg_logical/, pg_serial/replication slot·logical decoding·SSI
런타임pg_notify/, pg_snapshots/, pg_stat/, pg_stat_tmp/, pg_dynshmem/알림·스냅샷·통계·동적 공유 메모리
PGDATA 안의 파일은 절대 수동 편집하지 않는다. 특히 pg_wal/의 WAL 세그먼트를 임의 삭제하면 클러스터가 부팅 불가 상태가 됩니다. 백업·정리는 pg_archivecleanup 등 공식 도구를 거쳐야 합니다.

클러스터 생성: initdb

빈 디렉토리에 initdb를 실행하면 위의 골격이 만들어집니다.

# 일반적인 형태 (RHEL 계열 패키지가 깔린 경우)
sudo -u postgres /usr/pgsql-17/bin/initdb \
  -D /var/lib/pgsql/17/data \
  --encoding=UTF8 \
  --locale=C.UTF-8 \
  --data-checksums

자주 쓰는 옵션:

옵션의미
-D <dir>PGDATA 위치. 환경 변수 PGDATA로 대체 가능
--encoding=UTF8클러스터 기본 인코딩
--locale=C.UTF-8정렬·문자 분류 로케일. C 로케일은 ASCII 비교, 빠름
--data-checksums데이터 페이지 체크섬 활성 (이후 변경 불가, 운영 권장)
-U <user>슈퍼유저 이름 (기본 postgres)
--wal-segsize=<MB>WAL 세그먼트 크기 변경 (기본 16MB, 일부 워크로드에서 64MB·128MB 고려)

initdb는 다음을 수행한다:

  1. PGDATA 디렉토리 권한 0700(또는 0750)으로 설정
  2. PG_VERSION 작성
  3. 시스템 카탈로그 + template0·template1·postgres 생성
  4. postgresql.conf·pg_hba.conf 기본 파일 작성
initdb는 디렉토리가 비어 있어야 실행됩니다. 이미 파일이 있으면 “directory … is not empty” 오류로 거부한다 — 기존 클러스터를 실수로 덮어쓰지 못하게 막는 안전장치입니다.

한 호스트, 여러 클러스터

PostgreSQL은 한 호스트에 클러스터를 여러 개 띄우는 걸 정식으로 지원합니다. 각 클러스터는:

  • 별도 PGDATA
  • 별도 postmaster 프로세스
  • 별도 TCP 포트 (postgresql.confport 파라미터)
  • 별도 Unix 도메인 소켓 디렉토리
호스트 1대
├── 클러스터 A
│   ├── PGDATA: /var/lib/pgsql/17/data
│   ├── postmaster (PID 12345)
│   └── port 5432
└── 클러스터 B
    ├── PGDATA: /data/pg17-staging
    ├── postmaster (PID 12678)
    └── port 5433

Debian/Ubuntu는 pg_ctlcluster·pg_lsclusters 같은 클러스터 관리 도구를 기본 제공해, 한 호스트에 여러 클러스터를 일상적으로 운영하는 패턴을 전제합니다. RHEL 계열은 versioned 패키지(postgresql17-server)가 버전별로만 충돌을 피하므로, 같은 메이저로 여러 클러스터를 띄우려면 systemd 유닛을 복제해서 씁니다.

정리

  • PostgreSQL 인스턴스 = postmaster 1개 + PGDATA 1개
  • 공식 명칭은 “데이터베이스 클러스터” — 분산 클러스터 아님
  • 계층: cluster → database → schema → table/index/…
  • 한 연결은 한 데이터베이스만 봅니다. 다른 DB로 가려면 새 연결 또는 FDW/dblink
  • PGDATA 안에는 설정·실제 데이터·WAL·트랜잭션 상태·통계가 모두 모입니다. 수동 편집 금지
  • initdb로 클러스터 골격 생성합니다. --data-checksums 활성 권장 (이후 변경 불가)
  • 한 호스트에 클러스터 여러 개 가능 — 포트·소켓·PGDATA로 격리

다음 절(1.3)에서는 postmaster가 실제로 어떤 프로세스 가족을 띄우는지 — backend·background worker·autovacuum launcher 등 — 봅니다.