PostgreSQLXVII · Capacity, Maintenance and UpgradesMaintenance
Disk-full: distinguishing data, WAL, temp, archive and backup
What you'll learn
- Identify which filesystem filled, before acting
- Recover a cluster whose pg_wal filesystem is full
- Recognise why deleting WAL is the wrong response
- Separate the filesystems so one failure does not become all of them
Prerequisites
Verified against PostgreSQL 18.x · PostgreSQL (comparison targets) 17.11, 16.15 · PostgreSQL (support calendar) 18, 17, 16, 15, 14 supported · pgBackRest 2.59.1 · PgBouncer 1.25.2 · Patroni 4.1.5 · Ubuntu (host baseline) 26.04 LTS · 2026-08-27
“The disk is full” is five different incidents with five different responses. Establishing which filesystem filled is the first action, and it takes ten seconds.
Identify first
df -h \
/var/lib/postgresql/18/main \
/var/lib/postgresql/18/main/pg_wal \
/var/lib/postgresql/18/main/base/pgsql_tmp \
/archive \
/backup \
/var/log/postgresql
| Filled | Symptom | Response |
|---|---|---|
pg_wal | PANIC, cluster down and will not restart | Give it space. Never delete WAL |
| Data | Writes fail; cluster survives | Free space, then find the growth |
| Temp | Queries fail with a temp-file error | Lower work_mem, or fix the query |
| Archive | Archiving fails; pg_wal starts growing | Fix the destination. Lesson XIII-05 |
| Backup | Backups fail silently | Retention, and an alert |
| Logs | Logging fails; may block backends | Rotation. Lesson XVI-01 |
The archive row is the one that cascades: a full archive stops
archiving, unarchived segments cannot be recycled, and pg_wal fills
next. What looks like a WAL problem started somewhere else.
What a full pg_wal actually does
$ df -h /walspacetmpfs 48M 48M 0 100% /walspace$ grep -iE 'PANIC|FATAL|recovery|shut' /tmp/full.logPANIC: could not write to file "pg_wal/xlogtemp.61": No space left on device
LOG: database system was interrupted; last known up at 2026-08-27 23:31:00 UTC
FATAL: the database system is in recovery mode
LOG: database system was not properly shut down; automatic recovery in progress
FATAL: could not write to file "pg_wal/xlogtemp.69": No space left on device
LOG: shutting down due to startup process failure
LOG: database system is shut downThe recovery
$ ls -la $PGDATA/pg_wal
du -sh /walspace/pg_wal
mkdir -p /var/lib/postgresql/walrescue
cp -a /walspace/pg_wal/. /var/lib/postgresql/walrescue/
rm -f $PGDATA/pg_wal
ln -s /var/lib/postgresql/walrescue $PGDATA/pg_wallrwxrwxrwx ... pg_wal -> /walspace/pg_wal
48M /walspace/pg_wal
lrwxrwxrwx ... pg_wal -> /var/lib/postgresql/walrescue$ pg_ctl -D $PGDATA start; SELECT count(*) FROM fill;server started
LOG: database system was not properly shut down; automatic recovery in progress
LOG: redo starts at 0/17615F8
LOG: redo done at 0/3FFFDE8 system usage: CPU: user: 0.02 s, system: 0.00 s, elapsed: 0.03 s
LOG: checkpoint starting: end-of-recovery immediate wait
LOG: checkpoint complete: wrote 5094 buffers (31.1%) ... distance=41594 kB
LOG: database system is ready to accept connections
rows_recovered
----------------
60000Every committed row recovered, because no WAL was deleted.
The end-of-recovery checkpoint wrote 5,094 buffers — 31.1% of the pool — over a redo distance of 41,594 kB. That is the work that had accumulated and could not be written, now flushed.
Other ways to create space, in order of preference:
- Extend the filesystem. Best, if the storage allows it.
- Move
pg_walto another filesystem and symlink, as above. - Delete something else on that filesystem — logs, an old backup.
- Fix what was retaining WAL, which is the actual cause: a failing
archive, an abandoned slot,
wal_keep_size. Lesson XII-03.
Step 4 is the only one that stops it recurring.
Prevention
Separate filesystems. pg_wal, data, and the archive on different
volumes means one filling does not take the others with it. This is the
single highest-value structural decision in this lesson.
Alert at 75% on pg_wal specifically, not on the data volume — they
fill at completely different rates.
Bound what retains WAL. max_slot_wal_keep_size, from lesson
XIV-06, converts an unbounded pg_wal into an invalidated slot, which is
a task rather than an outage.
Watch pg_stat_archiver. A failing archive is a pg_wal problem
that has not happened yet.
What to take from this
- Identify which filesystem filled before doing anything. Five filesystems, five responses.
- A full archive cascades into a full
pg_wal. The symptom is not the cause. - Measured: a full
pg_walproduced aPANIC, recovery then failed for the same reason, and the cluster would not start. - Never delete WAL segments, and
pg_resetwalis not a disk-space tool. - The fix is space: extend, move and symlink, or delete something else. Then fix what was retaining WAL.
- Measured: after moving
pg_wal, all 60,000 committed rows recovered. - Separate filesystems, alert on
pg_walat 75%, and keep a ballast file.
Cross-course references
- Linux for Production Sysadmins — Part XIV (Filesystems) and Part XVI (LVM) cover finding what actually filled and whether it can be grown in place, and Part LXXX (Common failure scenarios) covers the reflex responses that make this worse.
- Ceph & Distributed Storage — Part LXIV (Nearfull, backfillfull and full) and Part LXV (Why full clusters are dangerous) cover the same failure where the storage system stops accepting writes for everyone.
- Observability for Production Sysadmins — Part XVIII (Alerting rules) covers alerting on each filesystem separately, since the response differs per volume.
Quiz
Knowledge check · 6 questions
Q1. A cluster whose pg_wal filesystem filled has PANICked and will not restart. What distinguishes this from a full data filesystem?
Q2. pg_wal has filled. Which action recovers the cluster without losing data?
Q3. Why is exhausting WAL space a PANIC rather than an ordinary error?
Q4. Which measures reduce the risk or impact of a full pg_wal? Select all that apply.
Q5. A full archive destination can cause pg_wal to fill even though nothing is wrong with the pg_wal filesystem itself.
Q6. Walk through responding to a full pg_wal filesystem, and explain why deleting WAL is the wrong instinct.
Passing score: 75%. Answers are checked in this browser.