]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Wake LSN waiters before recovery target stop
authorAlexander Korotkov <akorotkov@postgresql.org>
Thu, 29 Jan 2026 07:47:09 +0000 (09:47 +0200)
committerAlexander Korotkov <akorotkov@postgresql.org>
Thu, 29 Jan 2026 07:47:09 +0000 (09:47 +0200)
Move WaitLSNWakeup() immediately after ApplyWalRecord() so waiters are
signaled even when recoveryStopsAfter() breaks out for pause/promotion
targets.

Discussion: https://postgr.es/m/9533608f-f289-44bd-b881-9e5a73203c5b%40iki.fi
Discussion: https://postgr.es/m/CABPTF7Wdq6KbvC3EhLX3Pz%3DODCCPEX7qVQ%2BE%3DcokkB91an2E-A%40mail.gmail.com
Reported-by: Heikki Linnakangas <hlinnaka@iki.fi>
Author: Xuneng Zhou <xunengzhou@gmail.com>

src/backend/access/transam/xlogrecovery.c

index 117d8d8bb6b47e6b129efa09538bf7c60d9b8bf6..a81dcbb5d79b02b4f22624692e6b4891b94c0391 100644 (file)
@@ -1841,13 +1841,6 @@ PerformWalRecovery(void)
                         */
                        ApplyWalRecord(xlogreader, record, &replayTLI);
 
-                       /* Exit loop if we reached inclusive recovery target */
-                       if (recoveryStopsAfter(xlogreader))
-                       {
-                               reachedRecoveryTarget = true;
-                               break;
-                       }
-
                        /*
                         * If we replayed an LSN that someone was waiting for then walk
                         * over the shared memory array and set latches to notify the
@@ -1858,6 +1851,13 @@ PerformWalRecovery(void)
                                 pg_atomic_read_u64(&waitLSNState->minWaitedLSN[WAIT_LSN_TYPE_STANDBY_REPLAY])))
                                WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_REPLAY, XLogRecoveryCtl->lastReplayedEndRecPtr);
 
+                       /* Exit loop if we reached inclusive recovery target */
+                       if (recoveryStopsAfter(xlogreader))
+                       {
+                               reachedRecoveryTarget = true;
+                               break;
+                       }
+
                        /* Else, try to fetch the next WAL record */
                        record = ReadRecord(xlogprefetcher, LOG, false, replayTLI);
                } while (record != NULL);