307 lines
8.8 KiB
Plaintext
307 lines
8.8 KiB
Plaintext
# PostgreSQL Production Configuration
|
|
# Custom PHP Framework - Production Optimized Settings
|
|
# PostgreSQL 16
|
|
|
|
# ============================================================================
|
|
# CONNECTIONS AND AUTHENTICATION
|
|
# ============================================================================
|
|
|
|
# Listen on all network interfaces for Docker networking
|
|
listen_addresses = '*'
|
|
|
|
# Maximum number of concurrent connections
|
|
max_connections = 100
|
|
|
|
# Reserved connections for superuser emergency access
|
|
superuser_reserved_connections = 3
|
|
|
|
# ============================================================================
|
|
# MEMORY CONFIGURATION
|
|
# ============================================================================
|
|
|
|
# Shared memory for cache (25% of RAM, adjust based on available memory)
|
|
# For 4GB RAM server: 1GB
|
|
# For 8GB RAM server: 2GB
|
|
# For 16GB RAM server: 4GB
|
|
shared_buffers = 2GB
|
|
|
|
# Memory for complex sorts (per operation)
|
|
work_mem = 16MB
|
|
|
|
# Memory for maintenance operations (VACUUM, CREATE INDEX)
|
|
maintenance_work_mem = 256MB
|
|
|
|
# Maximum memory for autovacuum workers
|
|
autovacuum_work_mem = 128MB
|
|
|
|
# Effective cache size (hint for query planner, 50-75% of RAM)
|
|
effective_cache_size = 6GB
|
|
|
|
# ============================================================================
|
|
# WRITE-AHEAD LOG (WAL)
|
|
# ============================================================================
|
|
|
|
# WAL level for replication and point-in-time recovery
|
|
wal_level = replica
|
|
|
|
# Minimum size of past WAL files
|
|
min_wal_size = 1GB
|
|
|
|
# Maximum size of WAL files
|
|
max_wal_size = 4GB
|
|
|
|
# Number of WAL sender processes (for replication)
|
|
max_wal_senders = 3
|
|
|
|
# Number of replication slots
|
|
max_replication_slots = 3
|
|
|
|
# WAL keep size (for replication lag)
|
|
wal_keep_size = 1GB
|
|
|
|
# Synchronous commit (trade-off between durability and performance)
|
|
# on: Full durability (safest, slower)
|
|
# remote_apply: Wait for replica to apply (if using streaming replication)
|
|
# local: Wait for local flush (balanced)
|
|
# off: Fastest but risk of data loss on crash (NOT recommended for production)
|
|
synchronous_commit = on
|
|
|
|
# Checkpoint frequency (time between checkpoints)
|
|
checkpoint_timeout = 15min
|
|
|
|
# Target checkpoint completion time (fraction of checkpoint_timeout)
|
|
checkpoint_completion_target = 0.9
|
|
|
|
# ============================================================================
|
|
# QUERY PLANNING
|
|
# ============================================================================
|
|
|
|
# Random page cost (lower for SSD, higher for HDD)
|
|
# SSD: 1.0-1.1, HDD: 4.0
|
|
random_page_cost = 1.1
|
|
|
|
# Sequential page cost
|
|
seq_page_cost = 1.0
|
|
|
|
# Effective I/O concurrency (number of concurrent disk I/O operations)
|
|
# SSD: 200, HDD: 2-4
|
|
effective_io_concurrency = 200
|
|
|
|
# ============================================================================
|
|
# PARALLELISM
|
|
# ============================================================================
|
|
|
|
# Maximum number of parallel workers per query
|
|
max_parallel_workers_per_gather = 2
|
|
|
|
# Maximum number of parallel maintenance workers
|
|
max_parallel_maintenance_workers = 2
|
|
|
|
# Maximum number of parallel workers (total across all sessions)
|
|
max_parallel_workers = 4
|
|
|
|
# ============================================================================
|
|
# LOGGING
|
|
# ============================================================================
|
|
|
|
# Log destination
|
|
log_destination = 'stderr'
|
|
|
|
# Logging collector (rotate logs automatically)
|
|
logging_collector = on
|
|
|
|
# Log directory
|
|
log_directory = 'log'
|
|
|
|
# Log filename pattern (include date for rotation)
|
|
log_filename = 'postgresql-%Y-%m-%d.log'
|
|
|
|
# Log rotation age (daily)
|
|
log_rotation_age = 1d
|
|
|
|
# Log rotation size (500MB per file)
|
|
log_rotation_size = 500MB
|
|
|
|
# Truncate logs on rotation
|
|
log_truncate_on_rotation = on
|
|
|
|
# Log line prefix (include timestamp, user, database, PID)
|
|
log_line_prefix = '%t [%p] %u@%d '
|
|
|
|
# Log connections
|
|
log_connections = on
|
|
|
|
# Log disconnections
|
|
log_disconnections = on
|
|
|
|
# Log duration of statements (in milliseconds)
|
|
# Log only slow queries (>500ms)
|
|
log_min_duration_statement = 500
|
|
|
|
# Log lock waits (statements waiting for locks)
|
|
log_lock_waits = on
|
|
|
|
# Log checkpoints
|
|
log_checkpoints = on
|
|
|
|
# Log autovacuum activity
|
|
log_autovacuum_min_duration = 0
|
|
|
|
# ============================================================================
|
|
# AUTOVACUUM
|
|
# ============================================================================
|
|
|
|
# Enable autovacuum
|
|
autovacuum = on
|
|
|
|
# Maximum number of autovacuum workers
|
|
autovacuum_max_workers = 3
|
|
|
|
# Naptime between autovacuum runs
|
|
autovacuum_naptime = 1min
|
|
|
|
# Minimum number of updated/deleted tuples before vacuum
|
|
autovacuum_vacuum_threshold = 50
|
|
|
|
# Minimum number of inserted tuples before analyze
|
|
autovacuum_analyze_threshold = 50
|
|
|
|
# Fraction of table size to add to vacuum threshold
|
|
autovacuum_vacuum_scale_factor = 0.1
|
|
|
|
# Fraction of table size to add to analyze threshold
|
|
autovacuum_analyze_scale_factor = 0.05
|
|
|
|
# Cost delay for autovacuum (throttling)
|
|
autovacuum_vacuum_cost_delay = 10ms
|
|
|
|
# Cost limit for autovacuum
|
|
autovacuum_vacuum_cost_limit = 200
|
|
|
|
# ============================================================================
|
|
# STATISTICS
|
|
# ============================================================================
|
|
|
|
# Track activity across all databases
|
|
track_activities = on
|
|
|
|
# Track counts of rows accessed
|
|
track_counts = on
|
|
|
|
# Track I/O timing
|
|
track_io_timing = on
|
|
|
|
# Track functions
|
|
track_functions = all
|
|
|
|
# ============================================================================
|
|
# CONNECTION POOLING SUPPORT
|
|
# ============================================================================
|
|
|
|
# Prepared statements (use with PgBouncer in transaction pooling mode)
|
|
# For PgBouncer: set to 'auto' or create prepared statements per transaction
|
|
# For direct connections: 'on' for better performance
|
|
# plan_cache_mode = auto
|
|
|
|
# ============================================================================
|
|
# STATEMENT TIMEOUT
|
|
# ============================================================================
|
|
|
|
# Maximum statement execution time (30 seconds)
|
|
# Prevents long-running queries from blocking
|
|
statement_timeout = 30s
|
|
|
|
# Lock timeout (10 seconds)
|
|
# Prevents long lock waits
|
|
lock_timeout = 10s
|
|
|
|
# Idle in transaction session timeout (5 minutes)
|
|
# Closes idle transactions automatically
|
|
idle_in_transaction_session_timeout = 5min
|
|
|
|
# ============================================================================
|
|
# SECURITY
|
|
# ============================================================================
|
|
|
|
# SSL configuration (if using SSL)
|
|
# ssl = on
|
|
# ssl_cert_file = '/path/to/server.crt'
|
|
# ssl_key_file = '/path/to/server.key'
|
|
# ssl_ca_file = '/path/to/ca.crt'
|
|
|
|
# Password encryption (scram-sha-256 is most secure)
|
|
password_encryption = scram-sha-256
|
|
|
|
# ============================================================================
|
|
# CLIENT CONNECTION DEFAULTS
|
|
# ============================================================================
|
|
|
|
# Default transaction isolation level
|
|
default_transaction_isolation = 'read committed'
|
|
|
|
# Timezone
|
|
timezone = 'UTC'
|
|
|
|
# Client encoding
|
|
client_encoding = 'UTF8'
|
|
|
|
# Locale settings
|
|
lc_messages = 'en_US.UTF-8'
|
|
lc_monetary = 'en_US.UTF-8'
|
|
lc_numeric = 'en_US.UTF-8'
|
|
lc_time = 'en_US.UTF-8'
|
|
|
|
# Default text search configuration
|
|
default_text_search_config = 'pg_catalog.english'
|
|
|
|
# ============================================================================
|
|
# PERFORMANCE TUNING NOTES
|
|
# ============================================================================
|
|
|
|
# These settings are optimized for:
|
|
# - 8GB RAM server
|
|
# - SSD storage
|
|
# - Mixed OLTP/OLAP workload
|
|
# - Connection pooling via PgBouncer (optional)
|
|
|
|
# Adjust based on your hardware:
|
|
#
|
|
# For 4GB RAM server:
|
|
# shared_buffers = 1GB
|
|
# effective_cache_size = 3GB
|
|
# work_mem = 8MB
|
|
#
|
|
# For 16GB RAM server:
|
|
# shared_buffers = 4GB
|
|
# effective_cache_size = 12GB
|
|
# work_mem = 32MB
|
|
#
|
|
# For HDD storage:
|
|
# random_page_cost = 4.0
|
|
# effective_io_concurrency = 2
|
|
|
|
# ============================================================================
|
|
# MONITORING QUERIES
|
|
# ============================================================================
|
|
|
|
# Check current connections:
|
|
# SELECT count(*) FROM pg_stat_activity;
|
|
|
|
# Check slow queries:
|
|
# SELECT pid, query, now() - query_start AS duration
|
|
# FROM pg_stat_activity
|
|
# WHERE state = 'active' AND now() - query_start > interval '5 seconds';
|
|
|
|
# Check database size:
|
|
# SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname))
|
|
# FROM pg_database ORDER BY pg_database_size(pg_database.datname) DESC;
|
|
|
|
# Check table bloat (vacuum needed):
|
|
# SELECT schemaname, tablename,
|
|
# pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
|
|
# FROM pg_tables WHERE schemaname = 'public' ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
|
|
|
|
# Check index usage:
|
|
# SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetch
|
|
# FROM pg_stat_user_indexes ORDER BY idx_scan ASC;
|