Oracle vs PostgreSQL - SGA 공유영역

ChoRong0824·2025년 12월 13일

Oracle vs PostgreSQL

아키텍처 다이어그램

핵심 비교표

구분Oracle SGAPostgreSQL Shared Memory
데이터 캐시Database Buffer CacheShared Buffers
캐시 알고리즘LRU (MRU/LRU End)Clock Sweep (LRU 변형)
복구 로그 버퍼Redo Log BufferWAL Buffers
SQL 캐시Shared Pool (Library Cache)없음 (각 Backend 로컬)
딕셔너리 캐시Data Dictionary CacheSystem Catalog Cache (로컬)
자동 메모리 관리SGA_TARGET (10g+)수동 설정 필요
프로세스 모델멀티스레드 지원프로세스 기반 (fork)

상세 비교

1. 데이터 버퍼 캐시

Oracle: Database Buffer Cache

특징

  • 모든 세션이 공유하는 단일 버퍼 풀
  • LRU 알고리즘으로 버퍼 관리
  • DB_CACHE_SIZE로 크기 지정
  • KEEP/RECYCLE/DEFAULT 버퍼 풀 분리 가능

버퍼 상태

  • Free Buffer: 빈 버퍼
  • Pinned Buffer: 현재 사용 중
  • Dirty Buffer: 변경됨 (디스크에 미기록)

PostgreSQL: Shared Buffers

특징

  • 모든 백엔드 프로세스가 공유
  • Clock Sweep 알고리즘 (LRU 변형, 더 효율적)
  • shared_buffers로 크기 지정
  • 일반적으로 RAM의 25% 권장

버퍼 상태

  • usage_count: 0~5 (접근 빈도)
  • dirty: 변경 여부
  • pinned: 현재 사용 중

차이점

  • Oracle은 순수 LRU, PostgreSQL은 Clock Sweep 사용
  • PostgreSQL이 오버헤드가 적음 (리스트 재정렬 불필요)

2. SQL 실행 계획 캐시 (가장 큰 차이!)

Oracle: Shared Pool (Library Cache)

┌─────────────────────────────────────┐
│          Library Cache              │
│  ┌─────────────────────────────┐   │
│  │ SQL: SELECT * FROM emp      │   │
│  │ Plan: Index Scan...         │───┼──► 모든 세션이 공유!
│  │ Hash: 0x7A3B2C1D            │   │
│  └─────────────────────────────┘   │
└─────────────────────────────────────┘

- 동일 SQL은 한 번만 파싱
- 실행 계획을 모든 세션이 공유
- 대소문자, 공백까지 정확히 일치해야 재사용

PostgreSQL: 로컬 Plan Cache (각 Backend별)

┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│  Backend 1   │  │  Backend 2   │  │  Backend 3   │
│ ┌──────────┐ │  │ ┌──────────┐ │  │ ┌──────────┐ │
│ │Plan Cache│ │  │ │Plan Cache│ │  │ │Plan Cache│ │
│ │(로컬)    │ │  │ │(로컬)    │ │  │ │(로컬)    │ │
│ └──────────┘ │  │ └──────────┘ │  │ └──────────┘ │
└──────────────┘  └──────────────┘  └──────────────┘
       ▲                ▲                 ▲
       │                │                 │
    독립적!          독립적!           독립적!

- 각 세션이 개별적으로 파싱
- Prepared Statement 사용시에만 세션 내 재사용
- 세션 종료시 캐시 사라짐

차이점

| 항목 | Oracle | PostgreSQL |
|------|--------|------------|
| 캐시 범위 | 전역 (모든 세션) | 로컬 (세션별) |
| 메모리 효율 | 높음 | 낮음 (중복 저장) |
| 동시성 | 래치 경합 가능 | 경합 없음 |
| 권장 사항 | 바인드 변수 사용 | Prepared Statement 사용 |

3. 복구 로그

Oracle: Redo Log Buffer → Redo Log Files

트랜잭션 발생
     │
     ▼
┌─────────────┐     LGWR      ┌─────────────┐
│ Redo Log    │ ───────────►  │ Redo Log    │
│ Buffer      │   (주기적)    │ Files       │
└─────────────┘               └─────────────┘
                                    │
                              ┌─────┴─────┐
                              ▼           ▼
                         ┌────────┐  ┌────────┐
                         │Group 1 │  │Group 2 │ (순환)
                         └────────┘  └────────┘

PostgreSQL: WAL Buffers → WAL Files

트랜잭션 발생
     │
     ▼
┌─────────────┐   WAL Writer   ┌─────────────┐
│ WAL         │ ───────────►   │ WAL         │
│ Buffers     │   (주기적)     │ Files       │
└─────────────┘                └─────────────┘
                                     │
                               (pg_wal/)
                               0000000100000001
                               0000000100000002
                               ...

공통점

  • 둘 다 Write-Ahead Logging 방식
  • 변경 전 로그를 먼저 기록
  • 장애 복구에 사용

차이점

| 항목 | Oracle Redo | PostgreSQL WAL |
|------|-------------|----------------|
| 파일 구조 | 그룹/멤버 (순환) | 연속 세그먼트 |
| 아카이브 | Archive Log | WAL Archive |
| 복제 | Data Guard | Streaming Replication |

4. 프로세스 아키텍처

Oracle: 멀티프로세스 + 멀티스레드 옵션

┌─────────────────────────────────────────┐
│              Oracle Instance            │
├─────────────────────────────────────────┤
│                                         │
│  Background Processes:                  │
│  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐  │
│  │ DBWn │ │ LGWR │ │ CKPT │ │ SMON │  │
│  └──────┘ └──────┘ └──────┘ └──────┘  │
│  ┌──────┐ ┌──────┐ ┌──────┐           │
│  │ PMON │ │ RECO │ │ ARCn │           │
│  └──────┘ └──────┘ └──────┘           │
│                                         │
│  Server Processes (세션당):             │
│  ┌────────────────────────────────┐    │
│  │ Dedicated / Shared Server      │    │
│  └────────────────────────────────┘    │
│                                         │
└─────────────────────────────────────────┘

PostgreSQL: 순수 프로세스 기반 (fork)

┌─────────────────────────────────────────┐
│           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) |

메모리 파라미터 비교

Oracle 주요 파라미터

-- 자동 메모리 관리 (권장)
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 주요 파라미터

# 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 캐시 포함 예상 크기

권장 설정 가이드

PostgreSQL 메모리 설정 공식 (16GB RAM 서버 기준)

┌─────────────────────────────────────────────────────────────┐
│                    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의 장점

  1. Shared Pool: SQL 캐시를 전역 공유 → 메모리 효율
  2. 자동 메모리 관리: SGA_TARGET으로 자동 분배
  3. Shared Server: 연결 풀링 내장
  4. 세밀한 튜닝: 다양한 버퍼 풀 옵션

PostgreSQL의 장점

  1. 단순한 구조: 이해하고 관리하기 쉬움
  2. 락 경합 적음: 로컬 캐시로 경합 최소화
  3. Clock Sweep: LRU보다 효율적인 버퍼 관리
  4. 오픈소스: 무료, 커뮤니티 활발

PostgreSQL 사용시 주의사항

  1. shared_buffers 필수 설정: 기본값(128MB)은 너무 작음
  2. work_mem 주의: 세션 × 연산당 할당되므로 과다 설정 위험
  3. 연결 풀링 필수: PgBouncer 등 외부 풀러 사용 권장
  4. Prepared Statement 활용: SQL 캐시 효과를 위해 필수

1. Oracle Instance와 PostgreSQL Instance 개념 차이

Oracle

Oracle에서 자주 쓰이는 공식적인 표현은 다음과 같다.

Oracle Instance = SGA (Shared Global Area) + Background Processes

  • Instance가 시작되면
    • SGA라는 하나의 큰 공유 메모리 풀이 할당되고
    • DBWR, LGWR 같은 백그라운드 프로세스들이 함께 기동된다.
  • Instance 종료 시
    • SGA는 OS에 반환되고
    • 모든 백그라운드 프로세스가 종료된다.

PostgreSQL

PostgreSQL에서도 실행 중인 서버를 넓은 의미에서 “인스턴스”라고 부르기도 하지만,

  • Oracle처럼 SGA라는 단일한 메모리 덩어리 개념은 없음
  • 대신 다음 구조로 이해하는 것이 정확하다.

PostgreSQL = shared memory 영역 + 다수의 프로세스 구조

즉, PostgreSQL은

  • postmaster 프로세스
  • 연결마다 생성되는 backend process
  • 일부 공유 메모리 영역
    을 중심으로 동작한다.

2. Oracle SGA 한 줄 요약

“인스턴스가 시작되면 크게 잡히는 공유 메모리 풀(SGA) 안에,
캐시 / SQL 파싱 / 로그 버퍼 같은 핵심 컴포넌트가 들어 있고,
DBWR / LGWR 같은 백그라운드 프로세스가 이를 중심으로 디스크와 동기화한다.”

Oracle SGA 대표 구성요소

  • Database Buffer Cache

    • 데이터 블록 캐시
    • 읽기/쓰기 모두 메모리에서 먼저 처리
  • Shared Pool

    • SQL 파싱 결과
    • 실행 계획
    • Data Dictionary Cache
    • “같은 SQL 재사용”의 핵심
  • Redo Log Buffer

    • 변경 이력(redo)을 메모리에 적재
    • LGWR가 redo log 파일로 기록

3. PostgreSQL에서는 SGA 대신 무엇이 중심인가?

PostgreSQL은 다음 4가지 관점으로 보면 가장 정확하다.


3.1 공유 메모리: shared_buffers

  • Oracle의 Database Buffer Cache에 가장 가까운 개념
  • 데이터 페이지를 캐싱하는 PostgreSQL의 공유 메모리 영역

중요한 차이점

  • PostgreSQL은 OS Page Cache를 적극 활용
  • shared_buffers를 RAM의 대부분으로 키우는 것이 항상 성능 향상으로 이어지지 않음
  • 공식 문서에서도 보통 전체 메모리의 25% 전후, 많아도 40% 이내를 권장

3.2 WAL 구조: wal_buffers + WAL 파일

  • Oracle의 Redo Log Buffer에 가장 가까운 개념
  • 변경 사항은 먼저 WAL(Write-Ahead Log)에 기록

구조 요약:

  • 변경 발생
  • WAL record → wal_buffers
  • 커밋 시 WAL 파일로 flush
  • 데이터 파일은 나중에 기록(checkpoint)

wal_buffers를 무작정 크게 잡아도 효과는 제한적


3.3 Oracle Shared Pool 같은 “전역 SQL 캐시”는 없다 (중요)

Oracle의 Shared Pool 특징:

  • SQL 파싱 결과 / 실행 계획을 전 세션이 공유
  • 라이브러리 캐시 기반의 강력한 SQL 재사용

PostgreSQL의 기본 전제:

  • 서버 전역 SQL 캐시 모델이 아님
  • 대표적인 SQL 재사용 방식은:
    • 세션 단위 PREPARE
    • 드라이버 수준 prepared statement
    • 커넥션 풀러(pgBouncer 등)

즉, 세션이 종료되면 prepared statement도 사라진다


3.4 프로세스 모델 차이: “연결 = 프로세스”

PostgreSQL은 process-per-connection 모델이다.

  • 클라이언트 1개 연결
    • 서버 backend process 1개 생성
  • 각 backend는 독립된 프로세스
  • 하지만 shared_buffers, wal_buffers 같은 공유 메모리는 함께 사용

이 점이 Oracle의 멀티스레드/서버 프로세스 모델과 가장 큰 차이다.


4. Oracle SGA ↔ PostgreSQL 구성요소 대응표 (유사 개념 기준)

Oracle 구성요소PostgreSQL 대응 개념핵심 차이
Database Buffer Cacheshared_buffersPG는 OS 페이지 캐시 의존도가 큼
Redo Log Bufferwal_buffers + WALWAL이 내구성의 핵심 축
Shared Pool없음 (세션 단위 PREPARE)전역 SQL 캐시 전제 약함
LRU/MRU 버퍼 관리clock-sweep 알고리즘교체 알고리즘 자체가 다름
Instance (SGA + BG)postmaster + backend + shared memory멀티프로세스 구조 강조

5. 아키텍처 다이어그램 비교

5.1 Oracle 아키텍처 (Instance 중심)

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]

5.2 PostgreSQL 아키텍처 (Shared Memory + Process-per-Connection)

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

6. 정리 한 줄 요약

Oracle: “큰 SGA 하나 + 그걸 중심으로 움직이는 백그라운드 프로세스”

PostgreSQL: “shared memory + 연결마다 backend 프로세스 + WAL 중심 설계”

👉 그래서 Oracle 사고방식(SGA 튜닝 그대로)을 PostgreSQL에 적용하면 거의 항상 삐끗한다.

7. 참고 & 출처

Oracle


PostgreSQL


추가로 이해에 매우 좋은 외부 자료

  • InterDB – PostgreSQL Buffer Manager (Clock-sweep 포함)
    PostgreSQL Buffer Manager 내부 동작을 코드/구조 관점에서 상세 설명
    (Hironobu SUZUKI, InterDB)
    👉 https://www.interdb.jp/pg/pgsql08.html
profile
정진, "어제보다 더 나은 오늘이 되자"

0개의 댓글