1. 아키텍처

항목 MySQL PostgreSQL
프로세스 모델 스레드 기반 (단일 프로세스 + 멀티 스레드) 프로세스 기반 (커넥션당 fork)
커넥션 비용 가벼움 무거움 → PgBouncer 필수
기본 max_connections 151 100
스토리지 엔진 플러그인 방식 (InnoDB, MyISAM 등) 단일 통합 엔진

프로세스 모델 비교

MySQL — 스레드 기반

[ 생성 ]
pthread_create() → 새 스레드 생성
  - 스택만 할당
  - 프로세스 메모리 공유
  - 수십 μs

[ 메모리 ]
스레드 1개 ≈ 256KB ~ 1MB
  - 스택 + thread-local 변수
  - Buffer Pool, 카탈로그는 공유

[ 단점 ]
- 격리 부족: 한 스레드 메모리 violation → mysqld 전체 죽음
- 동시성 제어 복잡: 메모리 공유로 mutex/lock 곳곳에 필요

PostgreSQL — 프로세스 기반

[ 생성 ]
fork() → 새 프로세스 생성
  - 페이지 테이블 복사 + PCB 생성
  - 수 ms

[ 메모리 ]
backend 1개 ≈ 10MB
  - 별도 프로세스라 공유 안 됨
  - work_mem, 카탈로그 캐시 각자 보유

[ 단점 ]
- 연결 생성 비용 큼 (fork 자체가 무거움)
- 연결당 메모리 사용량 큼 → PgBouncer 필요한 이유

PgBouncer

역할: 영구 연결을 임시 연결처럼 동작시키는 매칭 브로커 → backend 프로세스 수 축소로 자원 절감

Before (PgBouncer 없이)

HikariCP                Postgres
conn1 ════════════════ backend #1   (영구 1:1 매칭)
conn2 ════════════════ backend #2

After (PgBouncer 적용)

[HikariCP Conn1] ──TCP A──→ [PgBouncer] ─TCP X─→ [backend #1]
                                        ─TCP Y─→ [backend #2]
                                        ─TCP Z─→ [backend #3]
                                            ↑
                                  트랜잭션마다 매번 다름

HikariCP는 "커넥션 100개"를 들고 있다고 생각하지만, 실제 Postgres backend는 20개만 돌 수도 있음. HikariCP Connection 수 ≠ Postgres backend 수


HikariCP