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>;
Cause
Fix
Bad plan
ANALYZE, raise statistics target
Missing index
Add covering / partial index
Sort spill
Raise work_mem
Bloat
VACUUM / 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;
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
Symptom
Action
High network lag
Tune TCP, dedicated link
Apply lag on standby
Faster disk, fewer queries on standby
WAL flood
wal_compression, batch writes
Logical: subscriber slow
Add 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