Commits on Aug 22, 2026
-
Enforce minRecoveryPoint check regardless of archive recovery mode
Previously, the recovery code only enforced the minRecoveryPoint check when ArchiveRecoveryRequested was true (i.e., standby.signal or recovery.signal existed). This meant that after pg_rewind - which sets minRecoveryPoint but does not create signal files - the server could open for connections without having replayed enough WAL, exposing inconsistent data. The scenario occurs when the source server has recycled WAL segments near the divergence point (e.g., after an explicit CHECKPOINT followed by VACUUM FULL). pg_rewind succeeds because the target's WAL is available for block change detection, but the source's WAL at the divergence point is missing. Recovery replays only the old timeline's WAL and stops short of minRecoveryPoint. The data files contain tuples from the source with transaction IDs beyond the replayed nextXid, making them invisible through MVCC and causing errors like "could not open relation with OID 2610" when accessing system catalogs. Fix by making the minRecoveryPoint FATAL unconditional: if recovery set minRecoveryPoint and we didn't reach it, that's always an error, whether or not archive recovery was explicitly requested. Also adds a TAP test that verifies that the server fails to start up with a proper error instead of the previous behavior without WAL arcihiving enabled, and properly starts up and restores the database with WAL archiving. Reported-by: Andrew Pogrebnoi <absourd.noise@gmail.com>