본문으로 건너뛰기

10.1 postgresql.conf 깊이 보기

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

설정 적용 범위와 시점

변경 방식​

방식적용 시점보존
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 = lz4 # PG 15+, on은 pglz
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 # 모든 worker 풀 상한
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과 워크로드 패턴으로 결정