1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Re-read standby LSN after recovery ends

WaitForLSN() samples the current position before checking whether
recovery is still in progress. If recovery reaches the target and ends
between those operations, the promotion path can compare against the
stale sample and incorrectly return NOT_IN_RECOVERY.

Read the position again after observing that recovery has ended, before
deciding whether promotion reached the target.

Author: Xuneng Zhou <xunengzhou@gmail.com>
Discussion: https://postgr.es/m/CABPTF7U0gW5%2B-4oL7-qdML-yerZxUb7ku4QXp7JxCYo0qyJ_Tw%40mail.gmail.com
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
Backpatch-through: 19
This commit is contained in:
Alexander Korotkov
2026-09-12 23:30:03 +03:00
parent d61f9c90f2
commit 8c7a74c323

View File

@@ -488,11 +488,19 @@ WaitForLSN(WaitLSNType lsnType, XLogRecPtr targetLSN, int64 timeout)
if (WaitLSNTypeRequiresRecovery(lsnType) && !RecoveryInProgress())
{
/*
* Recovery was ended, but check if target LSN was already
* Recovery has ended, but check if target LSN was already
* reached.
*/
deleteLSNWaiter(lsnType);
/*
* Recovery may have advanced the current position after
* currentLSN was read above. Once RecoveryInProgress() returns
* false, the final position is stable, so read it again before
* deciding whether promotion reached the target.
*/
currentLSN = GetCurrentLSNForWaitType(lsnType);
if (PromoteIsTriggered() && targetLSN <= currentLSN)
return WAIT_LSN_RESULT_SUCCESS;
return WAIT_LSN_RESULT_NOT_IN_RECOVERY;