Re: Fix XLogFileReadAnyTLI silently applying divergent WAL from wrong timeline

From: Andrey Borodin <x4mmm(at)yandex-team(dot)ru>
To: Stepan Tyagushev <stepa20060226(at)gmail(dot)com>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>, suryapoondla4(at)gmail(dot)com
Subject: Re: Fix XLogFileReadAnyTLI silently applying divergent WAL from wrong timeline
Date: 2026-08-20 18:48:55
Message-ID: EEE7F2CD-B365-4C2B-86BB-F8A3C2C8EFB8@yandex-team.ru
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Stepan,

On 17 Aug 2026, Stepan Tyagushev wrote:
> The discussion in that thread ultimately led to patch [2]; note the
> added
> check in src/backend/access/transam/xlogrecovery.c.
>
> Previously we'd unconditionally kill the walreceiver in the
> XLOG_FROM_STREAM handler; now we check whether it's actually
> streaming,
> and
> if it's in WALRCV_WAITING state we leave it alone.

Thank you for pointing this out. The production cluster was running the
current minor release at the time of the report. In any case, I
rechecked the test on a tree that already contains 17b2d5ec759, and
there is still a smaller window. After
walrcv_endstreaming() returns and while
WalRcvFetchTimeLineHistoryFiles() runs, the shared state is still
WALRCV_STREAMING. WALRCV_WAITING is set only later by
WalRcvWaitForStartPosition(). If startup wakes in that interval, the
check added by 17b2d5ec759 still calls XLogShutdownWalRcv().

I also checked the negative direction of test 054. I kept its
deterministic WakeupRecovery() and injection point, but removed
WALRCV_SWITCHING_TIMELINE. Startup then enters XLogShutdownWalRcv() and
waits for the walreceiver to exit instead of reaching
RecoveryRetrieveRetryInterval. The test fails as expected. With the new
state it passes. So failure to reproduce this without the injection
point seems to be a matter of the window being short.

No need to manually reproduce the problem, it is simulated in the test.
And test is failing if we do not apply the fix.

> Since we already have a general WALRCV_WAITING state, why do we need
> to
> introduce another specific state just to clarify what exactly we are
> waiting for?

WALRCV_WAITING means that walreceiver is ready for new instructions.
That is not yet true while it is fetching the history file, so setting
WAITING earlier would allow startup to request another stream before the
fetch finishes. The separate state distinguishes those two conditions.

Nevertheless, this is independent from the main problem in this thread:
XLogFileReadAnyTLI applying a divergent segment from an older timeline.
The extra walreceiver restart is much less serious, and the additional
state deserves its own discussion. Maybe I should move patches 0002/0003
to a separate thread and keep the next version here focused on 0001.

I also saw Surya's review of 0001. The comments about the conservative
switch-point behavior, diagnostics, and positive test coverage are
valuable, and I agree with them. I am not ready to post a v3 addressing
them yet, but I hope to do that soon.

Thank you!

Best regards, Andrey Borodin.

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Jeff Davis 2026-08-20 18:49:10 Re: Crash issue in PG18.5 regression
Previous Message Andrey Borodin 2026-08-20 18:43:29 Re: walsummarizer can get stuck when switching timelines