PostgreSQL pg_wal Disk Exhaustion & Server Crash: Emergency WAL Evacuation & Resilient Storage Architecture
WAL accumulation due to failing archive_command or orphaned replication slots, emergency triage, and permanent max_slot_wal_keep_size safeguards.
Operational Verification & Reliability Metadata
The error string is a symptom, not the root cause. Do not restart the server blindly. Run the diagnostic queries below to pinpoint the actual failure mode.
▸Symptom
PostgreSQL aborts abruptly with a PANIC error:
PANIC: could not write to file "pg_wal/xlogtemp.12345": No space left on device
FATAL: the database system is in recovery mode▸What You See in Production
The instance terminates instantly. Attempts to restart fail during recovery due to zero write capacity. df -h reveals 100% capacity on the WAL partition.
▸Root Cause Matrix
| Probability | Root Cause | Description |
|---|---|---|
| %55 | Archive Command Failure | S3 or NFS target unreachable; PostgreSQL holds unarchived segments indefinitely. |
| %30 | Orphaned Replication Slot | Inactive replica keeps holding WAL retention threshold. |
| %15 | Checkpoint Throttling | Large batch operations exceeding WAL allocation thresholds. |
▸EMERGENCY RUNBOOK (0-5 min)
rm -rf pg_wal/*!** Deleting pre-checkpoint WAL files corrupts the database cluster.# 1. Inspect filesystem and segments
df -h
ls -lh $PGDATA/pg_wal/ | wc -l
# 2. Release emergency ballast file
rm -f /var/lib/postgresql/emergency_disk_buffer.bin
# 3. Check replication slots and drop offline slot
psql -U postgres -c "SELECT slot_name, active FROM pg_replication_slots;"
psql -U postgres -c "SELECT pg_drop_replication_slot('offline_replica_slot');"▸PERMANENT BLUEPRINT
- 1Dedicated Mount Point: Isolate
pg_walon a dedicated partition (/pgwal). - 2Retention Bounds: Configure
max_slot_wal_keep_size = 32GB. - 3Telemetry: Alert on
pg_stat_archiver.failed_count > 0.
▸Verification
SELECT count(*) AS total_wal_files, pg_size_pretty(count(*) * 16 * 1024 * 1024) AS total_wal_size FROM pg_ls_waldir();
SELECT archived_count, failed_count FROM pg_stat_archiver;Other Database Error Triage Playbooks
Other battle-tested diagnostic guides for high-severity database errors.
PostgreSQL Connection Exhaustion & too many clients Triage
Root causes of FATAL: sorry, too many clients already and remaining connection slots errors, read-only pg_stat_activity diagnosis with privilege boundaries, and two-tier pooling mitigation.
PostgreSQL password authentication failed: Root Cause and Fix
Four root causes of psql password authentication failed: incorrect password, md5/SCRAM mismatch, pg_hba.conf rule ordering, and port/cluster confusion. Step-by-step triage.
PostgreSQL connection refused: 8-Step Definitive Triage
Difference between connection refused, timeout, and no pg_hba entry; triage for listen_addresses, port conflicts, firewalls, and Docker container mappings.