[DB] PostgreSQL: 프로세스 모델, MVCC, WAL, 확장성
PostgreSQL, Postgres, postmaster, VACUUM, TOAST, psql
정의
PostgreSQL 은 오픈소스 ORDBMS. 1986 UC Berkeley POSTGRES 의 후예. MVCC, 확장 가능 타입, JSONB, full-text search, GIS (PostGIS), 벡터 (pgvector) 등 무거운 데이터 시스템 의 표준.
프로세스 모델
flowchart TB
Postmaster[postmaster<br/>master process] --> BG[Background workers]
BG --> WAL_W[WAL writer]
BG --> BG_W[Background writer]
BG --> Checkpointer[Checkpointer]
BG --> Autovacuum[Autovacuum launcher]
BG --> Stats[Stats collector]
Postmaster -->|fork| C1["Backend 1<br/>(connection)"]
Postmaster -->|fork| C2[Backend 2]
Postmaster -->|fork| C3[Backend N]
IMPORTANT
프로세스 per connection. 1000 연결 = 1000 OS 프로세스. connection pool (PgBouncer) 가 거의 필수.
MVCC + VACUUM
자세한 건 mvcc 참고. PostgreSQL 의 dead tuple 누적 → VACUUM 으로 회수.
flowchart LR
Update[UPDATE 한 행] --> NewVer[새 버전 tuple]
Update --> DeadVer["옛 버전 tuple<br/>(dead)"]
Auto[autovacuum<br/>주기적 실행] --> DeadVer
Auto -->|회수| Space[빈 공간]
| VACUUM 종류 | 동작 |
|---|---|
VACUUM | dead tuple 표시, 공간 회수 |
VACUUM ANALYZE | + 통계 갱신 |
VACUUM FULL | table rewrite. LOCK 필요. 운영 중 금지 |
| autovacuum | 자동 |
CAUTION
autovacuum 이 따라잡지 못하면 pg_stat_user_tables.n_dead_tup 증가 → 쿼리 느려짐 + transaction ID wrap-around 위험.
WAL (Write-Ahead Log)
sequenceDiagram
Client->>Backend: UPDATE ...
Backend->>WAL: write log record
Backend->>SharedBuffer: page dirty
Backend-->>Client: COMMIT OK
Note over Backend: WAL fsync 후 commit
Checkpointer->>Disk: dirty page → 데이터 파일
- COMMIT = WAL fsync 면 OK. 데이터 파일은 나중에 checkpoint 시.
- crash recovery = WAL replay.
- replication 도 WAL streaming.
TOAST (큰 컬럼 압축)
The Oversized-Attribute Storage Technique
row size > 2KB 이면:
1. 압축 (LZ4 / pglz)
2. 그래도 크면 → toast 테이블에 *분할 저장*
대용량 텍스트 / JSONB / bytea 가 자동 처리. 사용자 코드 불필요.
핵심 도구
| 도구 | 의미 |
|---|---|
psql | CLI |
pg_dump / pg_restore | 백업 |
pg_basebackup | physical 백업 |
pg_rewind | replica → primary 빠른 동기화 |
pgbench | 벤치마크 |
EXPLAIN | 쿼리 plan |
pg_stat_* | 통계 view |
EXPLAIN ANALYZE
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM users WHERE email = 'koa@x.com';
자세한 건 query-explain-plan 참고.
인덱스 종류
| 인덱스 | 용도 |
|---|---|
| B-tree | 일반 (default) |
| Hash | 등가 검색만 |
| GIN | 다값 (배열, JSONB, full-text) |
| GiST | 공간, 범위 |
| SP-GiST | 공간 partitioning |
| BRIN | 큰 시계열 (작은 인덱스) |
| Bloom | 다컬럼 (확률적) |
자세한 건 gin-gist-hash-indexes 참고.
확장 (Extension)
CREATE EXTENSION postgis; -- 공간
CREATE EXTENSION pgvector; -- 벡터
CREATE EXTENSION pg_stat_statements; -- 쿼리 통계
CREATE EXTENSION pg_trgm; -- 트라이그램 (LIKE 최적화)
CREATE EXTENSION timescaledb; -- 시계열
PostgreSQL 의 최대 강점. 코어를 확장 으로 거대화.
흔한 함정
WARNING
SELECT *+ 인덱스 only scan 기대 = TOAST 컬럼 있으면 table fetch 강제. 필요 컬럼만.- 너무 많은 인덱스 = INSERT/UPDATE 느려짐. 사용 안 되는 인덱스
pg_stat_user_indexes.idx_scan = 0으로 식별. pg_dump의 논리 백업 만 의존 = 대용량은 시간 폭증. pg_basebackup + WAL archive 가 정통.- autovacuum disable = transaction ID wrap-around → DB 정지. 절대 끄지 말 것.
관련 위키
이 글의 용어 (7개)
- [DB Internals] B-Tree와 B+Tree 인덱싱database-internals
- 정의 B-Tree (B+ Tree) 는 거의 모든 RDB 의 인덱스 자료구조. balanced tree, 디스크 I/O 최소화 설계. 특징: - 균형 (balanced): 모든 …
- [DB Internals] MVCC: Multi-Version Concurrency Controldatabase-internals
- 정의 MVCC (Multi-Versioning Concurrency Control) 는 트랜잭션 간 격리를 여러 버전의 row 로 구현. 동시 read / write 가 락 없이…
- [DB] EXPLAIN 읽기: scan, join, sort, costdatabase-internals
- 정의 EXPLAIN = 쿼리 실행 계획 표시. EXPLAIN ANALYZE = 실제로 실행 + 실제 시간 측정. Scan 종류 | Scan | 의미 | 적합 | |---|---|…
- [DB] GIN / GiST / Hash / BRIN: 비-B-tree 인덱스database-internals
- 정의 B-tree 외 PostgreSQL 의 특수 인덱스 들. 자세한 B-tree 는 참고. | 인덱스 | 적합 | |---|---| | B-tree | = < > BETWEEN…
- [DB] MySQL / InnoDB: clustered index, redo log, MVCCdatabase-internals
- 정의 MySQL + InnoDB (기본 스토리지 엔진) 의 clustered index + redo log 기반 행 기반 RDBMS. 웹 / SaaS 의 가장 흔한 backbon…
- [DB] Transaction Isolation Levels: 완벽 가이드database-internals
- 정의 Transaction Isolation Level (트랜잭션 격리 수준) = 동시에 실행되는 여러 트랜잭션이 서로의 변경을 어디까지 볼 수 있는지 규정하는 수준. ACID …
- [DB] WAL: Write-Ahead Log, crash recovery, replication 의 토대database-internals
- 정의 Write-Ahead Log (WAL) = 데이터 변경 전 로그를 먼저 디스크에 기록. 모든 모던 RDB / KV / 분산 시스템의 내구성 기반. 핵심 약속: 로그가 디스크…
이 개념을 다룬 위키 페이지 (28)
- wiki[AWS] RDS Multi-AZ + Read Replica
- wiki[Concurrency] Connection Pool: DB, HTTP, gRPC 의 공통 패턴
- wiki[DB Internals] B+ Tree 내부: leaf linked list, range scan
- wiki[DB Internals] B-Tree 내부: split, merge, search 알고리즘
- wiki[DB Internals] CHAR / VARCHAR / TEXT / JSONB: 문자열 타입 비교
- wiki[DB] GIN / GiST / Hash / BRIN: 비-B-tree 인덱스
- wiki[DB Internals] GIN Index 깊이: 구조, jsonb_path_ops, tsvector
- wiki[DB] MongoDB: 문서 DB, WiredTiger, replica set, aggregation
- wiki[DB] MySQL / InnoDB: clustered index, redo log, MVCC
- wiki[PostgreSQL] JSONB: 장점과 단점, 인덱싱, 사용 패턴
- wiki[DB] EXPLAIN 읽기: scan, join, sort, cost
- wiki[DB Internals] R-Tree: 공간 인덱스, MBR, split
- wiki[DB] Sharding vs Partitioning: 수평 확장의 두 얼굴
- wiki[DB] SQLite: 단일 파일, WAL 모드, edge / mobile
- wiki[DB] Transaction Isolation Levels: 완벽 가이드
- wiki[DB] WAL: Write-Ahead Log, crash recovery, replication 의 토대
- wiki[Django] Q / F / Case / When / Database Functions
- wiki[Django] Transactions: atomic, on_commit, savepoint
- wiki[DRF] Filtering: django-filter, SearchFilter, OrderingFilter
- wiki[K8s] StatefulSet: 순서 보장, 고유 ID, 영속 스토리지
- wikiMySQL
- wikiSQL
- wiki[SQL] Data Types
- wiki[SQL] DCL TCL
- wiki[SQL] DDL
- wiki[SQL] DML
- wiki[SQL] GROUP BY
- wiki[SQL] JOIN
💬 댓글