본문 바로가기
운영체제(OS)/Docker

Postgresql 18.3 postgresql.conf

by JLearn 2026. 3. 18.

Claude Code에서 작성한 개발/스테이징/운영 postgresql.conf 파일 입니다.


개발 postgresql.conf

# =============================================================
# postgresql.conf - 개발 환경 (dev)
# 목표: 빠른 피드백, 전체 쿼리 로깅, WAL 최소화
# =============================================================

# ── 연결 ───────────────────────
listen_addresses = '*'
port = 5432
max_connections = 50

# ── 타임존 ──────────────────────
timezone = 'Asia/Seoul'
log_timezone = 'Asia/Seoul'

# ── 메모리 ──────────────────────
shared_buffers = 128MB
work_mem = 8MB
maintenance_work_mem = 64MB
effective_cache_size = 512MB
# shm_size(256MB) > shared_buffers(128MB) ✓

# ── 비동기 I/O (PG18 신기능, 개발은 sync도 무방) ──
io_method = sync

# ── WAL 설정 (개발: 최소화) ───────────────
wal_level = minimal          # 복제·아카이브 불필요, 최소 WAL 생성
# wal_level=minimal이면 max_wal_senders=0 강제
max_wal_senders = 0
wal_buffers = 4MB            # 기본값 수준 (shared_buffers의 1/32)
synchronous_commit = off     # 개발: 비동기 커밋으로 속도 우선
                             # 크래시 시 마지막 수 트랜잭션 유실 가능 (개발 허용)

# 체크포인트 (개발: 빠른 재시작 위해 짧게)
checkpoint_timeout = 5min
max_wal_size = 512MB
min_wal_size = 32MB
checkpoint_completion_target = 0.9
checkpoint_warning = 30s     # 체크포인트가 30초 넘으면 경고

# WAL 압축 (PG15+, lz4가 zstd보다 CPU 낮음)
wal_compression = lz4

# WAL 아카이브: 개발은 비활성화
archive_mode = off

# ── 로그 설정 ────────────────────────
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB
log_truncate_on_rotation = on

# 개발: 모든 쿼리 + 실행계획 파라미터 기록
log_min_duration_statement = 0      # 전체 쿼리 기록
log_statement = 'all'
log_error_verbosity = verbose
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '

# 유용한 개발용 로그
log_checkpoints = on
log_connections = on
log_disconnections = on
log_lock_waits = on
log_temp_files = 0                  # 임시파일 모두 기록
log_autovacuum_min_duration = 0     # autovacuum 전체 기록
deadlock_timeout = 1s

# ── Autovacuum ─────────────────────
autovacuum = on
autovacuum_max_workers = 2          # 개발: 부하 최소화
autovacuum_naptime = 2min
autovacuum_vacuum_scale_factor = 0.2
autovacuum_analyze_scale_factor = 0.1

# ── 통계 ──────────────────────────
track_activities = on
track_counts = on
track_io_timing = on
track_wal_io_timing = on            # PG15+

스테이징 postgresql.conf

# =============================================================
# postgresql.conf - 스테이징 환경 (staging)
# 목표: 운영과 동일 설정 + 디버깅 여지 확보
# =============================================================

# ── 연결 ────────────────────────
listen_addresses = '*'
port = 5432
max_connections = 100

# ── 타임존 ───────────────────────
timezone = 'Asia/Seoul'
log_timezone = 'Asia/Seoul'

# ── 메모리 ───────────────────────
shared_buffers = 512MB
work_mem = 16MB
maintenance_work_mem = 128MB
effective_cache_size = 1536MB
# shm_size(768MB) > shared_buffers(512MB) ✓

# ── 비동기 I/O (PG18, Ubuntu 24.04 커널 6.x 지원) ─
io_method = io_uring
io_combine_limit = 128kB

# ── WAL 설정 (스테이징: 운영에 준함) ──────
wal_level = replica          # 복제 구성 테스트 가능
max_wal_senders = 3          # 스탠바이·백업 연결 허용
wal_keep_size = 512MB        # 스탠바이 지연 대비 WAL 보관량

# WAL 버퍼: shared_buffers의 1/32 (max 64MB 자동 캡)
# PG는 보통 자동 계산하지만 명시 권장
wal_buffers = 16MB

# 동기 커밋: 스테이징은 운영과 동일하게 on 유지
synchronous_commit = on

# 체크포인트
checkpoint_timeout = 10min
max_wal_size = 2GB
min_wal_size = 256MB
checkpoint_completion_target = 0.9
checkpoint_warning = 60s

# WAL 압축
wal_compression = lz4

# 아카이브: 스테이징은 로컬 테스트용 (운영은 S3 등 외부로)
archive_mode = on
archive_command = 'test ! -f /var/lib/postgresql/wal/archive/%f && cp %p /var/lib/postgresql/wal/archive/%f'
archive_timeout = 300        # 5분마다 강제 WAL 세그먼트 전환

# ── 로그 설정 ────────────────────
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB
log_truncate_on_rotation = on

# 스테이징: 500ms 이상 쿼리 기록 (운영보다 낮게 설정해 성능 이슈 조기 발견)
log_min_duration_statement = 500
log_statement = 'ddl'        # DDL은 항상 기록
log_error_verbosity = default
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '

log_checkpoints = on
log_connections = on
log_disconnections = off
log_lock_waits = on
log_temp_files = 10MB        # 10MB 이상 임시파일만 기록
log_autovacuum_min_duration = 250ms
deadlock_timeout = 1s

# ── Autovacuum ────────────────
autovacuum = on
autovacuum_max_workers = 3
autovacuum_naptime = 1min
autovacuum_vacuum_scale_factor = 0.1
autovacuum_analyze_scale_factor = 0.05
autovacuum_vacuum_cost_delay = 5ms

# ── 통계 ─────────────────────
track_activities = on
track_counts = on
track_io_timing = on
track_wal_io_timing = on

운영 postgresql.conf

# =============================================================
# postgresql.conf - 운영 환경 (prod)
# 목표: 안정성·성능·복구가능성 최우선 (16GB RAM / 8 Core 기준)
# RAM 용량 변경 시 shared_buffers, effective_cache_size 재산정 필수
# =============================================================

# ── 연결 ────────────────────────
listen_addresses = '*'
port = 5432
max_connections = 200
# 실무 팁: 애플리케이션에 PgBouncer 붙이면 max_connections 50~100으로 낮춰도 됨
# PgBouncer가 있으면 오히려 더 나은 성능 (connection overhead 제거)

# ── 타임존 ───────────────────────
timezone = 'Asia/Seoul'
log_timezone = 'Asia/Seoul'

# ── 메모리 ───────────────────────
# Rule of thumb: shared_buffers = RAM × 25%, effective_cache_size = RAM × 75%
shared_buffers = 4GB           # 16GB RAM × 25%

# work_mem 기존 64MB -> 32MB 설정변경
work_mem = 32MB                # 위험: max_connections × work_mem이 RAM 초과 가능
                               # 세션별 정렬/해시 시 사용. 신중하게 설정
maintenance_work_mem = 1GB     # VACUUM, CREATE INDEX, pg_restore 시 사용
effective_cache_size = 12GB    # 16GB RAM × 75% (OS 페이지 캐시 추정치)
huge_pages = try               # Transparent Huge Pages 시도 (memlock unlimited 필요)
# shm_size(3GB) > shared_buffers(4GB) ← 주의!
# shm_size는 shared_buffers보다 커야 함. 위 compose의 shm_size: 5gb로 올릴 것

# ── 비동기 I/O (PG18 핵심 성능 기능) ────────

io_method = io_uring           # Ubuntu 24.04 커널 6.8+ 필수 -> DB 시작 에러 발생 시 주석 처리

io_combine_limit = 128kB       # 연속 I/O 병합 최대 크기

# ── WAL 설정 (운영: 핵심) ───────────────
wal_level = replica            # 복제·논리복제·아카이브 모두 지원
max_wal_senders = 5            # 스탠바이 + 백업 도구 연결 슬롯

# WAL 버퍼: 쓰기 집약 워크로드에서 병목 방지
# 기본값(shared_buffers의 1/32)보다 크게, 최대 64MB 이상도 가능
wal_buffers = 64MB

# 동기 커밋: 운영 DB 핵심 안전장치
# on   = COMMIT 응답 전 WAL이 디스크에 flush됨을 보장 (데이터 유실 없음)
# off  = 성능 향상 but 크래시 시 최대 wal_writer_delay(200ms) 분량 유실
# remote_write = 스탠바이 수신 확인 후 응답 (동기 복제 구성 시)
synchronous_commit = on

# WAL 라이터 주기 (synchronous_commit=off 환경에서만 의미 있음)
wal_writer_delay = 200ms

# WAL 레벨 설정 (크기 vs 안전성 트레이드오프)
checkpoint_timeout = 15min         # 체크포인트 간격: 길수록 WAL 많이 쌓임
max_wal_size = 4GB                 # 체크포인트 사이 최대 WAL 크기
min_wal_size = 512MB               # WAL 세그먼트 최소 재사용 크기
checkpoint_completion_target = 0.9 # 체크포인트 I/O를 timeout의 90% 기간에 분산
checkpoint_warning = 30s           # 체크포인트가 예상보다 이르면 경고 → alert 연동

# WAL 압축: CPU 소모 vs WAL 크기 절감 (lz4 권장: CPU overhead 최소)
wal_compression = lz4

# WAL 아카이브: 운영 필수 (PITR - Point In Time Recovery 기반)
archive_mode = on
# 실무: S3 등 외부 스토리지로 전송 (pgbackrest, barman, wal-g 연동)
# 예시 (wal-g):
# archive_command = 'wal-g wal-push %p'
# 예시 (로컬 테스트):

# 해당 디렉토리가 호스트와 컨테이너에 실제 존재하고 권한이 있어야 함
archive_command = 'test ! -f /var/lib/postgresql/wal/archive/%f && cp %p /var/lib/postgresql/wal/archive/%f'
archive_timeout = 300          # 5분마다 강제 WAL 세그먼트 전환 (백업 lag 최소화)

# 복구 관련
restore_command = 'cp /var/lib/postgresql/wal/archive/%f %p'
recovery_target_timeline = 'latest'

# WAL 보관 (스탠바이 지연 또는 슬롯 사용 시 유실 방지)
wal_keep_size = 2GB            # 복제 슬롯 없을 때 스탠바이용 WAL 보관
max_replication_slots = 10     # 논리복제, PgBouncer, 백업 도구용

# ── 플래너 설정 (운영 최적화) ───────────
random_page_cost = 1.1         # SSD 환경: 기본값 4.0 → 1.1로 낮춰 인덱스 우선
effective_io_concurrency = 256 # SSD IOPS 고려 (NVMe: 256~1000)
parallel_workers_per_gather = 4

# ── 로그 설정 ─────────────────────
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 200MB
log_truncate_on_rotation = on

# 운영: 1초 이상 쿼리만 기록 (디스크 I/O 최소화)
log_min_duration_statement = 1000
log_statement = 'none'         # DDL도 audit 솔루션(pgAudit)으로 별도 처리
log_error_verbosity = default
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '

log_checkpoints = on
log_connections = off          # 운영: 접속 로그 끄기 (트래픽 많을 시 로그 폭증)
log_disconnections = off
log_lock_waits = on            # 잠금 대기: 항상 기록 (장애 원인 분석 필수)
log_temp_files = 100MB         # 100MB 이상 임시파일만 기록
log_autovacuum_min_duration = 500ms
deadlock_timeout = 1s

# ── Autovacuum (운영 튜닝) ─────────────
autovacuum = on
autovacuum_max_workers = 5     # 테이블 수 많을수록 늘릴 것
autovacuum_naptime = 1min
# 공격적 vacuum (운영 테이블 bloat 방지)
autovacuum_vacuum_scale_factor = 0.05     # 5% 변경 시 vacuum
autovacuum_analyze_scale_factor = 0.02   # 2% 변경 시 analyze
autovacuum_vacuum_cost_delay = 2ms       # vacuum I/O 스로틀 (낮을수록 빠름)
autovacuum_vacuum_cost_limit = 400       # 기본 200 → 운영은 400으로 높임

# ── 통계 수집 (모니터링 연동: pg_stat_*, Prometheus) ──
track_activities = on
track_counts = on
track_io_timing = on
track_wal_io_timing = on       # PG15+
track_functions = pl           # 함수 레벨 통계

# 공유 메모리 내 통계 슬롯 (접속자 많을수록 늘릴 것)
pg_stat_statements.max = 10000
pg_stat_statements.track = all
shared_preload_libraries = 'pg_stat_statements'

댓글