]> git.ipfire.org Git - thirdparty/postgresql.git/commit
Fix cascading standby reconnect failure after archive fallback
authorÁlvaro Herrera <alvherre@kurilemu.de>
Wed, 29 Jul 2026 15:15:45 +0000 (17:15 +0200)
committerÁlvaro Herrera <alvherre@kurilemu.de>
Wed, 29 Jul 2026 15:15:45 +0000 (17:15 +0200)
commitb614de4876bb4e4264a99ec4c6f2582ad4e0ca8d
tree6b24dfe7ca6d538867195b0e064b76478d808ea5
parent9fa2c1ebd1757db6032cf81b53f973941be77747
Fix cascading standby reconnect failure after archive fallback

A cascading standby could fail to reconnect to its upstream standby with
"requested starting point ... is ahead of the WAL flush position" after
falling back to archive recovery.  This happened because archive
recovery processes whole segment files, so after replaying a segment the
cascade's next read position lands at the start of the following
segment, which is ahead of the upstream's flush position reported by
GetStandbyFlushRecPtr() (still inside the just-replayed segment).

Fix by having the walreceiver check the upstream's current WAL flush
position via IDENTIFY_SYSTEM before issuing START_REPLICATION.
IDENTIFY_SYSTEM already returns this position (as xlogpos), but
walrcv_identify_system() previously discarded it; now we have a use for
it.  If the requested start point exceeds the upstream's flush position
on the same timeline, the walreceiver waits for
wal_retrieve_retry_interval and retries.

The wait is limited to gaps of at most one WAL segment, which is the
expected case from the segment-granularity of archive recovery.  Larger
gaps indicate the upstream is genuinely behind, so START_REPLICATION is
allowed to proceed (and fail) normally, letting the startup process fall
back to other WAL sources.  The first wait is logged at LOG level;
subsequent waits are demoted to DEBUG1 to avoid log noise.  The
walreceiver honors wal_receiver_timeout during the wait, so it will exit
if the upstream doesn't catch up in time.

To preserve ABI compatibility on back branches, the flush position from
IDENTIFY_SYSTEM is communicated via a new global variable
(WalRcvIdentifySystemLsn) rather than changing the signature of
walrcv_identify_system().

The bug was introduced in Postgres 9.3 by commit abfd192b1b5b, which
added a flush-position check in StartReplication() that rejects requests
ahead of the upstream server's WAL flush position.

Author: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
Reviewed-by: Xuneng Zhou <xunengzhou@gmail.com>
Backpatch-through: 14
Discussion: https://postgr.es/m/CA+nrD2cTuTkkX5WXVZengTYYZbAO6zV8K+Tri-R0fbLFuoyMBA@mail.gmail.com
src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
src/backend/replication/logical/worker.c
src/backend/replication/walreceiver.c
src/backend/utils/activity/wait_event_names.txt
src/include/replication/walreceiver.h
src/test/recovery/meson.build
src/test/recovery/t/055_cascade_reconnect.pl [new file with mode: 0644]