
| 구분 | Oracle SGA | PostgreSQL Shared Memory |
|---|---|---|
| 데이터 캐시 | Database Buffer Cache | Shared Buffers |
| 캐시 알고리즘 | LRU (MRU/LRU End) | Clock Sweep (LRU 변형) |
| 복구 로그 버퍼 | Redo Log Buffer | WAL Buffers |
| SQL 캐시 | Shared Pool (Library Cache) | 없음 (각 Backend 로컬) |
| 딕셔너리 캐시 | Data Dictionary Cache | System Catalog Cache (로컬) |
| 자동 메모리 관리 | SGA_TARGET (10g+) | 수동 설정 필요 |
| 프로세스 모델 | 멀티스레드 지원 | 프로세스 기반 (fork) |
특징
버퍼 상태
특징
버퍼 상태
차이점
┌─────────────────────────────────────┐
│ Library Cache │
│ ┌─────────────────────────────┐ │
│ │ SQL: SELECT * FROM emp │ │
│ │ Plan: Index Scan... │───┼──► 모든 세션이 공유!
│ │ Hash: 0x7A3B2C1D │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
- 동일 SQL은 한 번만 파싱
- 실행 계획을 모든 세션이 공유
- 대소문자, 공백까지 정확히 일치해야 재사용
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Backend 1 │ │ Backend 2 │ │ Backend 3 │
│ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │
│ │Plan Cache│ │ │ │Plan Cache│ │ │ │Plan Cache│ │
│ │(로컬) │ │ │ │(로컬) │ │ │ │(로컬) │ │
│ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │
└──────────────┘ └──────────────┘ └──────────────┘
▲ ▲ ▲
│ │ │
독립적! 독립적! 독립적!
- 각 세션이 개별적으로 파싱
- Prepared Statement 사용시에만 세션 내 재사용
- 세션 종료시 캐시 사라짐
차이점
| 항목 | Oracle | PostgreSQL |
|------|--------|------------|
| 캐시 범위 | 전역 (모든 세션) | 로컬 (세션별) |
| 메모리 효율 | 높음 | 낮음 (중복 저장) |
| 동시성 | 래치 경합 가능 | 경합 없음 |
| 권장 사항 | 바인드 변수 사용 | Prepared Statement 사용 |
트랜잭션 발생
│
▼
┌─────────────┐ LGWR ┌─────────────┐
│ Redo Log │ ───────────► │ Redo Log │
│ Buffer │ (주기적) │ Files │
└─────────────┘ └─────────────┘
│
┌─────┴─────┐
▼ ▼
┌────────┐ ┌────────┐
│Group 1 │ │Group 2 │ (순환)
└────────┘ └────────┘
트랜잭션 발생
│
▼
┌─────────────┐ WAL Writer ┌─────────────┐
│ WAL │ ───────────► │ WAL │
│ Buffers │ (주기적) │ Files │
└─────────────┘ └─────────────┘
│
(pg_wal/)
0000000100000001
0000000100000002
...
공통점
차이점
| 항목 | Oracle Redo | PostgreSQL WAL |
|------|-------------|----------------|
| 파일 구조 | 그룹/멤버 (순환) | 연속 세그먼트 |
| 아카이브 | Archive Log | WAL Archive |
| 복제 | Data Guard | Streaming Replication |
┌─────────────────────────────────────────┐
│ Oracle Instance │
├─────────────────────────────────────────┤
│ │
│ Background Processes: │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ DBWn │ │ LGWR │ │ CKPT │ │ SMON │ │
│ └──────┘ └──────┘ └──────┘ └──────┘ │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ PMON │ │ RECO │ │ ARCn │ │
│ └──────┘ └──────┘ └──────┘ │
│ │
│ Server Processes (세션당): │
│ ┌────────────────────────────────┐ │
│ │ Dedicated / Shared Server │ │
│ └────────────────────────────────┘ │
│ │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ PostgreSQL Instance │
├─────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────┐ │
│ │ Postmaster │ │
│ │ (메인 프로세스) │ │
│ └───────────────┬────────────────────┘ │
│ │ fork() │
│ ┌────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │Backend│ │Backend│ │Backend│ │
│ │ 1 │ │ 2 │ │ N │ │
│ └──────┘ └──────┘ └──────┘ │
│ │
│ Background Workers: │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ BG │ │ WAL │ │Autovac │ │
│ │ Writer │ │ Writer │ │uum │ │
│ └────────┘ └────────┘ └────────┘ │
│ ┌────────┐ ┌────────┐ │
│ │Checkpnt│ │Stats │ │
│ │er │ │Collect │ │
│ └────────┘ └────────┘ │
│ │
└─────────────────────────────────────────┘
차이점
| 항목 | Oracle | PostgreSQL |
|------|--------|------------|
| 세션 처리 | Dedicated/Shared Server | 무조건 프로세스 fork |
| 컨텍스트 스위칭 | 스레드 (빠름) | 프로세스 (상대적 느림) |
| 메모리 사용 | 효율적 | 세션당 메모리 복제 |
| 연결 풀링 | 내장 (Shared Server) | 외부 필요 (PgBouncer) |
-- 자동 메모리 관리 (권장)
SGA_TARGET = 4G -- SGA 전체 크기
PGA_AGGREGATE_TARGET = 2G -- PGA 전체 크기
-- 수동 설정시
DB_CACHE_SIZE = 2G -- 버퍼 캐시
SHARED_POOL_SIZE = 500M -- 공유 풀
LOG_BUFFER = 64M -- 리두 로그 버퍼
LARGE_POOL_SIZE = 200M -- 라지 풀
# postgresql.conf
# 공유 메모리 (필수 설정!)
shared_buffers = 4GB # RAM의 25% 권장 (버퍼 캐시)
wal_buffers = 64MB # WAL 버퍼 (shared_buffers의 1/32)
# 로컬 메모리 (세션별)
work_mem = 256MB # 정렬/해시 조인용 (세션별!)
maintenance_work_mem = 1GB # VACUUM, CREATE INDEX용
temp_buffers = 32MB # 임시 테이블용
# 플래너 힌트
effective_cache_size = 12GB # OS 캐시 포함 예상 크기
┌─────────────────────────────────────────────────────────────┐
│ Total RAM: 16GB │
├─────────────────────────────────────────────────────────────┤
│ │
│ shared_buffers = 4GB (25%) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │████████████████████████████████ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ effective_cache_size = 12GB (75%) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │████████████████████████████████████████████████████ │ │
│ └─────────────────────────────────────────────────────┘ │
│ (shared_buffers + OS page cache 예상치) │
│ │
│ work_mem = 256MB │
│ (주의: 세션 × 쿼리당 할당되므로 과다 설정 위험!) │
│ 예: 100세션 × 256MB = 25GB 가능 → OOM 위험 │
│ │
│ maintenance_work_mem = 1GB │
│ (VACUUM, CREATE INDEX 등 관리 작업용) │
│ │
└─────────────────────────────────────────────────────────────┘
Oracle에서 자주 쓰이는 공식적인 표현은 다음과 같다.
Oracle Instance = SGA (Shared Global Area) + Background Processes
PostgreSQL에서도 실행 중인 서버를 넓은 의미에서 “인스턴스”라고 부르기도 하지만,
PostgreSQL = shared memory 영역 + 다수의 프로세스 구조
즉, PostgreSQL은
postmaster 프로세스backend process“인스턴스가 시작되면 크게 잡히는 공유 메모리 풀(SGA) 안에,
캐시 / SQL 파싱 / 로그 버퍼 같은 핵심 컴포넌트가 들어 있고,
DBWR / LGWR 같은 백그라운드 프로세스가 이를 중심으로 디스크와 동기화한다.”
Database Buffer Cache
Shared Pool
Redo Log Buffer
PostgreSQL은 다음 4가지 관점으로 보면 가장 정확하다.
shared_buffers중요한 차이점
shared_buffers를 RAM의 대부분으로 키우는 것이 항상 성능 향상으로 이어지지 않음wal_buffers + WAL 파일구조 요약:
wal_buffers
wal_buffers를 무작정 크게 잡아도 효과는 제한적
Oracle의 Shared Pool 특징:
PostgreSQL의 기본 전제:
PREPARE즉, 세션이 종료되면 prepared statement도 사라진다
PostgreSQL은 process-per-connection 모델이다.
shared_buffers, wal_buffers 같은 공유 메모리는 함께 사용이 점이 Oracle의 멀티스레드/서버 프로세스 모델과 가장 큰 차이다.
| Oracle 구성요소 | PostgreSQL 대응 개념 | 핵심 차이 |
|---|---|---|
| Database Buffer Cache | shared_buffers | PG는 OS 페이지 캐시 의존도가 큼 |
| Redo Log Buffer | wal_buffers + WAL | WAL이 내구성의 핵심 축 |
| Shared Pool | 없음 (세션 단위 PREPARE) | 전역 SQL 캐시 전제 약함 |
| LRU/MRU 버퍼 관리 | clock-sweep 알고리즘 | 교체 알고리즘 자체가 다름 |
| Instance (SGA + BG) | postmaster + backend + shared memory | 멀티프로세스 구조 강조 |
flowchart TB
Client[Client] --> SP[Server Process]
subgraph Instance[Oracle Instance]
subgraph SGA[SGA (Shared Memory)]
BC[Database Buffer Cache]
SHP[Shared Pool]
RLB[Redo Log Buffer]
end
DBWR[DBWR]
LGWR[LGWR]
end
SP --> BC
SP --> SHP
SP --> RLB
BC -->|lazy write| DBWR --> DF[Data Files]
RLB -->|redo flush| LGWR --> RLF[Online Redo Logs]
flowchart TB
App[Client / App] --> Postmaster[postmaster]
Postmaster --> BE1[backend process (conn 1)]
Postmaster --> BE2[backend process (conn 2)]
subgraph SharedMem[Shared Memory]
SB[shared_buffers]
WB[wal_buffers]
end
BE1 --> SB
BE2 --> SB
BE1 --> WB
BE2 --> WB
subgraph BG[Background Processes]
BGW[background writer]
CKP[checkpointer]
WALW[wal writer]
end
SB -->|dirty pages| BGW --> DF[(Data Files)]
SB -->|checkpoint flush| CKP --> DF
WB -->|WAL flush| WALW --> WAL[(WAL files)]
OSCache[(OS Page Cache)] --- DF
Oracle: “큰 SGA 하나 + 그걸 중심으로 움직이는 백그라운드 프로세스”
PostgreSQL: “shared memory + 연결마다 backend 프로세스 + WAL 중심 설계”
👉 그래서 Oracle 사고방식(SGA 튜닝 그대로)을 PostgreSQL에 적용하면 거의 항상 삐끗한다.
Oracle Database Concepts – Memory Architecture
SGA 구성요소(Buffer Cache, Shared Pool, Redo Log Buffer)와 Instance 메모리 구조 개요
👉 https://docs.oracle.com/en/database/oracle/oracle-database/23/cncpt/memory-architecture.html
Oracle Database – Database Buffer Cache
Buffer Cache가 LRU list + touch count 기반으로 관리되는 방식 설명
👉 https://tayoung00.tistory.com/17
PostgreSQL Documentation – Resource Consumption
shared_buffers 가이드(25% 시작점, OS Page Cache 의존, 40% 이상은 보통 효과 제한)
Background Writer 설명 포함
👉 https://www.postgresql.org/docs/current/runtime-config-resource.html
PostgreSQL Documentation – Write Ahead Log
WAL 구조, wal_buffers 특성, 커밋/플러시 동작 설명
👉 https://www.postgresql.org/docs/current/runtime-config-wal.html
PostgreSQL Documentation – How Connections Are Established
postmaster 역할, process-per-connection 모델 설명
👉 https://www.postgresql.org/docs/current/connect-estab.html
PostgreSQL Documentation – PREPARE
Prepared Statement가 세션 단위로 유지된다는 공식 설명
👉 https://www.postgresql.org/docs/current/sql-prepare.html
PostgreSQL Release Notes 8.1 – Buffer Manager (Clock Sweep)
PostgreSQL 버퍼 매니저가 clock-sweep 알고리즘을 사용하게 된 배경
👉 https://www.postgresql.org/docs/8.1/release-8-1.html