Your IT Lab

PostgreSQL 18 Docker WAL Corruption Recovery Guide

PostgreSQL 18 Docker WAL Corruption Recovery Guide

When PostgreSQL on Unraid fails to find a valid checkpoint record, pg_resetwal can force it to start. Use it only to regain access, then back up your data and rebuild fresh.

This guide is for Unraid OS

Problem

PostgreSQL fails to start with errors:

PANIC: could not locate a valid checkpoint record
invalid record length at 0/26546A8: expected at least 24, got 0
Solution: Reset WAL Using pg_resetwal

Step 1: Stop the Container
Go to Unraid Docker page
Stop the PostgreSQL container

Step 2: Enter Temporary Recovery Container

docker run -it --rm \ -v /mnt/user/appdata/postgresql18/18/docker:/var/lib/postgresql \ --entrypoint /bin/bash \ postgres:18

Important: Replace /mnt/user/appdata/postgresql18/18/docker with your actual data path.

Step 3: Switch to Postgres User

su - postgres

Step 4: Verify Data Directory Structure

ls -la /var/lib/postgresql/ cat /var/lib/postgresql/PG_VERSION

Should show "18"

You should see directories: base, global, pg_wal, pg_xact, etc.

Step 5: Run pg_resetwal

/usr/lib/postgresql/18/bin/pg_resetwal -f -D /var/lib/postgresql

Optional: Dry Run (Preview Without Changes)

/usr/lib/postgresql/18/bin/pg_resetwal -n -D /var/lib/postgresql

Expected Success Output

Write-ahead log reset

Step 6: Exit and Restart

exit # Exit postgres user
exit # Exit container

Restart Container
Go to Unraid Docker page

Start the PostgreSQL container

Check logs for successful startup

Step 7: Post-Recovery Actions ⚠️ IMPORTANT

7.1 Export Data Immediately

docker exec -it <container-name> pg_dumpall -U postgres > /mnt/user/appdata/postgresql18/backup_$(date +%Y%m%d).sql

7.2 Verify Backup

head -n 50 /mnt/user/appdata/postgresql18/backup_*.sql

7.3 Plan to Rebuild
The database is now in a "recovered but potentially inconsistent" state. Do not use it long-term.

Create a fresh PostgreSQL 18 container with empty data directory

Import the backup:

cat backup.sql | docker exec -i <new-container> psql -U postgres

Switch production to new container

Keep old container data as backup

File Structure Reference

Host Path (Unraid) Container Path
/mnt/user/appdata/postgresql18/18/docker/ /var/lib/postgresql/
/mnt/user/appdata/postgresql18/18/docker/pg_wal /var/lib/postgresql/pg_wal
/mnt/user/appdata/postgresql18/18/docker/base /var/lib/postgresql/base

pg_resetwal Command:

/usr/lib/postgresql/18/bin/pg_resetwal -f -D /var/lib/postgresql

(Not /var/lib/postgresql/data)

Quick Troubleshooting
Issue Solution
pg_resetwal: command not found

Use full path:

/usr/lib/postgresql/18/bin/pg_resetwal

Permission denied Ensure you're postgres user: su - postgres
Wrong data directory Check ls -la /var/lib/postgresql/ for PG_VERSION and base/
pg_resetwal fails with version error Verify cat /var/lib/postgresql/PG_VERSION shows 18

Warnings & Risks
⚠️ Data Loss: Last few transactions before crash may be lost

⚠️ Data Corruption: Database may have inconsistencies

⚠️ Emergency Tool: Use only to recover access, not as permanent fix

✅ Always Backup: Before any recovery operation

Prevention Measures
Enable WAL Archiving:

conf
archive_mode=on
archive_command='cp %p /path/to/archive/%f'

Regular Backups:
pg_basebackup -D /backup/base -Fp -P -U postgres

Monitor Disk Space: Prevent out-of-space errors

Use Stable Storage: Avoid network/NFS for data directory

Proper Shutdown: Always stop containers gracefully