Skip to content

fix(restore): fall back to pg_resetwal when WAL recovery fails#49

Merged
passcod merged 1 commit into
mainfrom
pg-resetwal-fallback
Jun 2, 2026
Merged

fix(restore): fall back to pg_resetwal when WAL recovery fails#49
passcod merged 1 commit into
mainfrom
pg-resetwal-fallback

Conversation

@passcod

@passcod passcod commented Jun 2, 2026

Copy link
Copy Markdown
Member

When a source snapshot is captured mid-online-backup the trailing WAL segments needed to complete recovery aren't present in the data dir, and postgres fails to start with WAL ends before end of online backup (or a related recovery error). Without intervention the init container crashloops indefinitely and the replica never comes up.

For an analytics replica the priority is availability over byte-perfect consistency. Add a pg_resetwal -f fallback in the postgres-single locale-fix step of the init script, with two stages:

  • Detected: if the failure log matches a known WAL-recovery signature (WAL ends before end of online backup, invalid record length at, database system was interrupted while in recovery, could not locate required checkpoint record), short-circuit directly to pg_resetwal + retry. Retrying the same command won't help when recovery itself is the blocker.
  • Undetected: if the failure doesn't match a known signature, try the same command once more — could be a transient catalog / I/O blip. Only if that retry also fails, run pg_resetwal as a last resort and retry once.

pg_resetwal does not restore missing data; it leaves the data dir at whatever state the snapshot captured. That's acceptable for read-only analytics — a replica that comes up with the snapshot's data is more useful than one that never comes up at all.

Unit test on the init script verifies both branches are present (signature detection, dual pg_resetwal calls, same-settings retry before the last-resort reset).

When a source snapshot is captured mid-online-backup the trailing WAL
segments needed to complete recovery are not present in the data
dir, and postgres fails to start with "WAL ends before end of online
backup" (or a related recovery error). Without intervention the init
container crashloops indefinitely.

For an analytics replica the priority is availability over byte-
perfect consistency. Add a pg_resetwal -f fallback in the postgres
--single locale-fix step in the init script, with two stages:

  - Stage 1 (detected): if the failure log matches a known WAL-
    recovery signature ("WAL ends before end of online backup",
    "invalid record length at", "database system was interrupted
    while in recovery", "could not locate required checkpoint
    record"), short-circuit directly to pg_resetwal + retry. Retrying
    the same command won't help when recovery itself is the blocker.

  - Stage 2 (undetected): if the failure doesn't match a known
    signature, try the same command once more — could be a transient
    catalog / I/O blip. Only if that retry also fails, run pg_resetwal
    as a last resort and retry once.

pg_resetwal does not restore missing data; it leaves the data dir at
whatever state the snapshot captured. That's acceptable for read-
only analytics — a replica that comes up with the snapshot's data
is more useful than one that never comes up at all.
@passcod passcod merged commit 6d0c183 into main Jun 2, 2026
18 checks passed
@passcod passcod deleted the pg-resetwal-fallback branch June 2, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant