From e3b4fb72b63d24ecd4807e5b561910f1fe3d73b6 Mon Sep 17 00:00:00 2001 From: alterego655 <824662526@qq.com> Date: Fri, 10 Apr 2026 11:05:46 +0800 Subject: [PATCH v7 3/7] Remove redundant WAIT FOR LSN caller-side pre-checks All five wakeup call sites duplicate WaitLSNWakeup()'s internal fast-path minWaitedLSN check and add an unnecessary NULL check on waitLSNState. Remove the inline pre-checks and call WaitLSNWakeup() directly. The fast-path check inside WaitLSNWakeup() already returns early when no waiter's target has been reached, so there is no performance difference. The waitLSNState NULL checks are also unnecessary: shared memory is fully initialized before any backend or auxiliary process starts, so waitLSNState is always non-NULL at these call sites. Reported-by: Andres Freund Discussion: https://postgr.es/m/jzq5shdewncpxc35r3s2mcfsmo4bjovkza5mnqf5bdfumhfi3g%40bglckf7dxmw5 Author: Xuneng Zhou --- src/backend/access/transam/xlog.c | 16 ++++++---------- src/backend/access/transam/xlogrecovery.c | 11 ++++------- src/backend/replication/walreceiver.c | 17 ++++++----------- 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index e39af79c03b..86c41bd3ae6 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -2936,12 +2936,10 @@ XLogFlush(XLogRecPtr record) WalSndWakeupProcessRequests(true, !RecoveryInProgress()); /* - * If we flushed an LSN that someone was waiting for, notify the waiters. + * Wake up processes waiting for primary flush LSN to reach current flush + * position. */ - if (waitLSNState && - (LogwrtResult.Flush >= - pg_atomic_read_u64(&waitLSNState->minWaitedLSN[WAIT_LSN_TYPE_PRIMARY_FLUSH]))) - WaitLSNWakeup(WAIT_LSN_TYPE_PRIMARY_FLUSH, LogwrtResult.Flush); + WaitLSNWakeup(WAIT_LSN_TYPE_PRIMARY_FLUSH, LogwrtResult.Flush); /* * If we still haven't flushed to the request point then we have a @@ -3126,12 +3124,10 @@ XLogBackgroundFlush(void) WalSndWakeupProcessRequests(true, !RecoveryInProgress()); /* - * If we flushed an LSN that someone was waiting for, notify the waiters. + * Wake up processes waiting for primary flush LSN to reach current flush + * position. */ - if (waitLSNState && - (LogwrtResult.Flush >= - pg_atomic_read_u64(&waitLSNState->minWaitedLSN[WAIT_LSN_TYPE_PRIMARY_FLUSH]))) - WaitLSNWakeup(WAIT_LSN_TYPE_PRIMARY_FLUSH, LogwrtResult.Flush); + WaitLSNWakeup(WAIT_LSN_TYPE_PRIMARY_FLUSH, LogwrtResult.Flush); /* * Great, done. To take some work off the critical path, try to initialize diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index c236e2b7969..4f2eaa36990 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -1782,14 +1782,11 @@ PerformWalRecovery(void) ApplyWalRecord(xlogreader, record, &replayTLI); /* - * If we replayed an LSN that someone was waiting for then walk - * over the shared memory array and set latches to notify the - * waiters. + * Wake up processes waiting for standby replay LSN to reach + * current replay position. */ - if (waitLSNState && - (XLogRecoveryCtl->lastReplayedEndRecPtr >= - pg_atomic_read_u64(&waitLSNState->minWaitedLSN[WAIT_LSN_TYPE_STANDBY_REPLAY]))) - WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_REPLAY, XLogRecoveryCtl->lastReplayedEndRecPtr); + WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_REPLAY, + XLogRecoveryCtl->lastReplayedEndRecPtr); /* Exit loop if we reached inclusive recovery target */ if (recoveryStopsAfter(xlogreader)) diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 9e40f066c97..07eac07b9ce 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -981,12 +981,10 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli) pg_atomic_write_membarrier_u64(&WalRcv->writtenUpto, LogstreamResult.Write); /* - * If we wrote an LSN that someone was waiting for, notify the waiters. + * Wake up processes waiting for standby write LSN to reach current write + * position. */ - if (waitLSNState && - (LogstreamResult.Write >= - pg_atomic_read_u64(&waitLSNState->minWaitedLSN[WAIT_LSN_TYPE_STANDBY_WRITE]))) - WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_WRITE, LogstreamResult.Write); + WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_WRITE, LogstreamResult.Write); /* * Close the current segment if it's fully written up in the last cycle of @@ -1028,13 +1026,10 @@ XLogWalRcvFlush(bool dying, TimeLineID tli) SpinLockRelease(&walrcv->mutex); /* - * If we flushed an LSN that someone was waiting for, notify the - * waiters. + * Wake up processes waiting for standby flush LSN to reach current + * flush position. */ - if (waitLSNState && - (LogstreamResult.Flush >= - pg_atomic_read_u64(&waitLSNState->minWaitedLSN[WAIT_LSN_TYPE_STANDBY_FLUSH]))) - WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_FLUSH, LogstreamResult.Flush); + WaitLSNWakeup(WAIT_LSN_TYPE_STANDBY_FLUSH, LogstreamResult.Flush); /* Signal the startup process and walsender that new WAL has arrived */ WakeupRecovery(); -- 2.39.5 (Apple Git-154)