본문으로 건너뛰기
10.1 postgresql.conf 깊이 보기

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 필요, 그 외는 reload
  • 메모리·WAL·autovacuum·planner·logging이 핵심 카테고리
  • 환경별 출발점은 RAM과 워크로드 패턴으로 결정
  • 변경은 하나씩, 변경 후 pg_settings + 모니터링 확인

다음 절(10.2)에서는 클러스터 자체를 다루는 명령 — pg_ctl, systemd를 봅니다.