Troubleshooting Common Issues

1. Diagnosing Slow Queries

SELECT query, calls, mean_exec_time, total_exec_time
  FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 20;
EXPLAIN (ANALYZE, BUFFERS, SETTINGS) <suspect query>;
CauseFix
Bad planANALYZE, raise statistics target
Missing indexAdd covering / partial index
Sort spillRaise work_mem
BloatVACUUM / pg_repack

2. Resolving Lock Contention

SELECT bl.pid AS blocked, ka.query AS blocking_query, kl.mode AS blocking_mode
  FROM pg_locks bl
  JOIN pg_stat_activity ba ON ba.pid = bl.pid
  JOIN pg_locks kl ON kl.locktype = bl.locktype AND kl.relation IS NOT DISTINCT FROM bl.relation
                  AND kl.pid <> bl.pid AND kl.granted
  JOIN pg_stat_activity ka ON ka.pid = kl.pid
 WHERE NOT bl.granted;

3. Fixing Connection Issues

ErrorCheck
no pg_hba.conf entrypg_hba.conf rules + reload
too many connectionsmax_connections, use PgBouncer
password authentication failedpassword_encryption, role exists
SSL requiredsslmode / cert paths
timeoutfirewall, listen_addresses

4. Handling Out of Memory Errors

# Linux: avoid OOM killer killing postgres
vm.overcommit_memory = 2
vm.overcommit_ratio  = 80
# Lower work_mem, max_connections; raise per-cgroup limits

5. Resolving Disk Space Issues

SELECT pg_size_pretty(pg_database_size(d.datname)), d.datname
  FROM pg_database d ORDER BY pg_database_size(d.datname) DESC;
SELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn))
  FROM pg_replication_slots;     -- inactive slots pin WAL!
Warning: Never rm files from pg_wal. Drop unused replication slots and let checkpointer recycle WAL.

6. Fixing Replication Lag

SymptomAction
High network lagTune TCP, dedicated link
Apply lag on standbyFaster disk, fewer queries on standby
WAL floodwal_compression, batch writes
Logical: subscriber slowAdd subscribers, partition publications

7. Handling Transaction ID Wraparound

SELECT datname, age(datfrozenxid),
       round(age(datfrozenxid)::numeric / 2000000000, 3) AS pct
  FROM pg_database ORDER BY age(datfrozenxid) DESC;
VACUUM FREEZE VERBOSE;
Warning: At ~2B XIDs DB enters read-only safety mode. Tune autovacuum_freeze_max_age and ensure autovacuum keeps up.

8. Debugging Function Errors

SET client_min_messages = debug1;
SET plpgsql.extra_errors  = 'all';
SET plpgsql.extra_warnings = 'all';
-- Add RAISE NOTICE in hot paths, or use GET STACKED DIAGNOSTICS

9. Resolving Permission Denied Errors

\dp schema.table
SELECT has_table_privilege('alice', 'orders', 'SELECT');
SELECT has_schema_privilege('alice', 'app', 'USAGE');
LayerRequired
DatabaseCONNECT
SchemaUSAGE
TableSELECT/INSERT/...
SequenceUSAGE, SELECT (for currval/nextval)

10. Analyzing PostgreSQL Logs

# postgresql.conf
logging_collector       = on
log_filename            = 'postgresql-%Y-%m-%d.log'
log_line_prefix         = '%m [%p] %u@%d %r %a '
log_min_duration_statement = 250ms
log_checkpoints         = on
log_lock_waits          = on
log_temp_files          = 0
log_autovacuum_min_duration = 0
Note: Pipe logs through pgBadger for HTML reports of slow queries, vacuum activity, errors.