Re: BUG: Cascading standby fails to reconnect after falling back to archive recovery
Marco Nenciarini <marco.nenciarini@enterprisedb.com>
From: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
To: Xuneng Zhou <xunengzhou@gmail.com>
Cc: Fujii Masao <masao.fujii@gmail.com>, pgsql-hackers@postgresql.org
Date: 2026-03-21T10:37:40Z
Lists: pgsql-hackers
Hi Xuneng, On Fri, Mar 21, 2026 at 10:07 AM Xuneng Zhou <xunengzhou@gmail.com> wrote: > > I think this rounds down to the start of segment that contains > targetPagePtr + reqLen. It does not round up. So if both standby have > replayed the same record, the cascade's startpoint would land at the > beginning of the current segment, which will provide a legitimate LSN > to upstream server. This case would be fine. Am I missing something > here? You're right that it rounds down, but the value being rounded is not the replay position. Let me trace the exact path: 1. XLogPageRead calls WaitForWALToBecomeAvailable(targetPagePtr + reqLen). After archive recovery finishes reading segment N, the next page request is for the first page of segment N+1, so this value is already in segment N+1. 2. WaitForWALToBecomeAvailable sets ptr = RecPtr (line 3843) and passes it to RequestXLogStreaming. 3. RequestXLogStreaming truncates to the segment boundary, but since the value is already at (or just past) the start of segment N+1, it stays at the start of N+1. 4. On the upstream side, GetStandbyFlushRecPtr returns replayPtr, which is the end of the last replayed record inside segment N. 5. Start of N+1 > replayPtr in N => "ahead of the WAL flush position". So the gap doesn't come from the truncation itself -- it comes from archive recovery processing whole segment files. After both nodes replay the same archived segment N, the cascade's next read position is already in N+1 while the upstream reports a position inside N. The truncation determines the exact startpoint (segment boundary) but the "ahead" condition exists regardless of it. I'll update the code comment in the patch to describe this more precisely. Best regards, Marco
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix scenario where streaming standby gets stuck at a continuation record.
- 066871980183 11.0 cited
-
Allow a streaming replication standby to follow a timeline switch.
- abfd192b1b5b 9.3.0 cited