본문으로 건너뛰기

10.1 postgresql.conf 깊이 보기

postgresql.conf에는 수백 개의 파라미터가 있습니다. 운영자가 모두 외울 필요는 없지만 실제 운영 행동에 영향을 주는 핵심 50개 정도는 익혀 두어야 합니다.

변경 방식 — 3가지

방식적용 시점보존
postgresql.conf 직접 편집reload 또는 restart영구
ALTER SYSTEM SET ...reloadpostgresql.auto.conf에 저장, 영구
SET <param> = ...즉시 (세션)세션 종료 시 사라짐
SET LOCAL <param> = ...즉시 (트랜잭션)트랜잭션 종료
ALTER DATABASE/ROLE ... SET ...다음 접속영구

운영 표준은 ALTER SYSTEM + reload입니다. 파일을 직접 편집하는 방식은 버전 관리·자동화에 불리합니다. 단, postgresql.auto.conf만 봐서는 변경 의도가 명확하지 않으니 변경 이력은 별도 문서로 남기길 권장합니다.

파라미터 카테고리

카테고리변경 시 적용
Connection / Authenticationreload (대부분), 일부는 restart
Resource Usage (메모리·디스크)restart (shared_buffers, max_connections 등) / reload
WAL / 복제restart (max_wal_senders) / reload
Query Planningreload — 옵티마이저 관련
Reporting / Loggingreload
Statisticsreload
Autovacuumreload
Locksrestart (max_locks_per_transaction)
Compatibility다양

확인:

SELECT name, context FROM pg_settings ORDER BY context, name;
-- context: 'postmaster'(restart), 'sighup'(reload), 'user'(SET), 'backend', 'superuser-backend' 등

context = postmaster이면 restart가 필요합니다. 그 외는 보통 reload로 충분합니다.

핵심 50개 파라미터 — 카테고리별

Connection

listen_addresses = '*' # 또는 'localhost,10.0.0.5'
port = 5432
max_connections = 200 # 동시 연결 상한 (restart 필요)
superuser_reserved_connections = 3

Memory

shared_buffers = 8GB # 호스트 RAM 25%, restart 필요
huge_pages = try # 가능하면 huge page
work_mem = 16MB # 노드당, 너무 크게 두지 말 것 (1.4)
maintenance_work_mem = 1GB # CREATE INDEX, VACUUM
autovacuum_work_mem = 256MB # autovacuum 별도
effective_cache_size = 24GB # 옵티마이저 힌트 (할당 아님)
temp_buffers = 32MB

WAL

wal_level = replica # 복제용 (logical은 더 많음)
synchronous_commit = on # 안전
wal_buffers = -1 # auto
max_wal_size = 8GB # 체크포인트 빈도 결정
min_wal_size = 2GB
checkpoint_timeout = 15min
checkpoint_completion_target = 0.9
wal_compression = on # WAL 압축 (LZ4 권장)
full_page_writes = on # 절대 off 금지

Archive / Replication

archive_mode = on
archive_command = '/usr/bin/pgbackrest archive-push %p'
archive_timeout = 60s

max_wal_senders = 10
max_replication_slots = 10
wal_keep_size = 1GB # 슬롯 없는 standby 보호
hot_standby = on # standby에서 read 허용
hot_standby_feedback = off # standby vacuum 충돌 vs primary BLOAT 트레이드오프

Autovacuum

autovacuum = on # 절대 off 금지
autovacuum_max_workers = 5
autovacuum_naptime = 30s
autovacuum_vacuum_cost_limit = 2000 # 큰 시스템은 키움
# 큰 테이블은 ALTER TABLE ... SET (autovacuum_vacuum_scale_factor = 0.02)

Planner / Cost

random_page_cost = 1.1 # SSD/NVMe
seq_page_cost = 1.0
cpu_tuple_cost = 0.01
cpu_index_tuple_cost = 0.005
cpu_operator_cost = 0.0025
effective_io_concurrency = 200 # NVMe
default_statistics_target = 100

Parallel

max_worker_processes = 16 # 모든 워커 풀 상한
max_parallel_workers = 12
max_parallel_workers_per_gather = 4
max_parallel_maintenance_workers = 4

Logging

log_destination = 'csvlog'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_rotation_age = 1d
log_rotation_size = 100MB
log_truncate_on_rotation = on
log_min_duration_statement = 1000 # 1s 이상 쿼리 로그
log_checkpoints = on
log_connections = on
log_disconnections = on
log_lock_waits = on
log_temp_files = 0 # 모든 temp file
log_autovacuum_min_duration = 1000
log_line_prefix = '%t [%p] %u@%d app=%a '

Statistics extensions

shared_preload_libraries = 'pg_stat_statements,auto_explain,pgaudit'

pg_stat_statements.max = 10000
pg_stat_statements.track = top
pg_stat_statements.track_utility = on
pg_stat_statements.save = on

auto_explain.log_min_duration = '1s'
auto_explain.log_analyze = on
auto_explain.log_buffers = on
auto_explain.log_triggers = off
auto_explain.log_nested_statements = on

Security

password_encryption = scram-sha-256
ssl = on
ssl_cert_file = '/etc/postgresql/ssl/server.crt'
ssl_key_file = '/etc/postgresql/ssl/server.key'
ssl_ca_file = '/etc/postgresql/ssl/ca.crt'
ssl_min_protocol_version = 'TLSv1.2'

idle_in_transaction_session_timeout = '5min'
statement_timeout = 0 # 글로벌 0, 세션·역할별 설정
lock_timeout = '5s'

Misc

timezone = 'Asia/Seoul'
log_timezone = 'Asia/Seoul'
datestyle = 'iso, ymd'
lc_messages = 'en_US.UTF-8' # 로그 영어가 검색·자동화에 유리
default_text_search_config = 'pg_catalog.simple'

max_locks_per_transaction = 128 # 파티션 많으면 키움 (restart)

검증 — pg_settings

-- 모든 비기본값
SELECT name, setting, unit, source, context
FROM pg_settings
WHERE source <> 'default'
ORDER BY name;

-- 변경 후 적용 여부
SELECT name, pending_restart FROM pg_settings WHERE pending_restart;

pending_restart = true인 파라미터가 있으면 restart 필요합니다.

환경별 권장 요약

워크로드shared_bufferswork_memmaintenance_work_memrandom_page_cost
일반 OLTP (64GB RAM, NVMe)16GB16MB1GB1.1
대용량 분석 (256GB RAM)64GB64MB4GB1.1
작은 인스턴스 (8GB RAM)2GB8MB256MB1.5
매우 write-heavy16GB16MB1GB1.1, max_wal_size 32GB

이 값들은 출발점일 뿐입니다. 실제 튜닝은 pg_stat_statements와 워크로드 분석을 거친 뒤에 합니다.

변경 절차

  1. pg_settings로 현재 값 확인
  2. 변경 사유 문서화
  3. ALTER SYSTEM SET ...
  4. pending_restart 확인 — restart 필요면 점검 시간 잡기
  5. reload (또는 restart)
  6. 다시 pg_settings로 검증
  7. 24~48시간 모니터링
경고

한 번에 여러 파라미터를 바꾸지 말 것. 무엇이 효과를 냈는지 알 수 없습니다. 변경은 하나씩 + 충분한 관찰 기간.

정리

변경은 ALTER SYSTEM 뒤 reload가 운영 표준이고, context = postmaster인 파라미터만 restart가 필요합니다. 한 번에 하나씩 바꾼 다음 pg_settings와 모니터링으로 효과를 확인하는 습관이 안전합니다.

  • 메모리·WAL·autovacuum·planner·logging이 핵심 카테고리
  • 환경별 출발점은 RAM과 워크로드 패턴으로 결정