From 62c410d50423cb1d568ea4054ccef8ab700d6912 Mon Sep 17 00:00:00 2001 From: Alex Speller <1217+alexspeller@users.noreply.github.com> Date: Fri, 16 Oct 2026 19:34:05 +0000 Subject: [PATCH] Recheck for WAL after a physical walsender joins wal_flush_cv WalSndWakeup() broadcasts wal_flush_cv, which only sets the latches of walsenders already on its waitlist. A physical walsender reads the flush pointer in XLogSendPhysical() but joins the waitlist only later, in WalSndWait(), so a flush in between woke nobody and the walsender slept until the standby's next status message. With a synchronous standby that stalls commits for up to wal_receiver_status_interval. Recheck the flush pointer once on the waitlist, as ConditionVariablePrepareToSleep() requires. Oversight in bc971f4025c. --- src/backend/replication/walsender.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 9f21c7c8dfe..d7c70c2e33e 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -4143,7 +4143,31 @@ WalSndWait(uint32 socket_events, long timeout, uint32 wait_event) if (wait_event == WAIT_EVENT_WAIT_FOR_STANDBY_CONFIRMATION) ConditionVariablePrepareToSleep(&WalSndCtl->wal_confirm_rcv_cv); else if (MyWalSnd->kind == REPLICATION_KIND_PHYSICAL) + { ConditionVariablePrepareToSleep(&WalSndCtl->wal_flush_cv); + + /* + * WalSndWakeup() only sets the latch of walsenders already on the + * CV's waitlist, so a flush between XLogSendPhysical() reading the + * flush pointer and the call above woke nobody. Recheck now that + * we're on the waitlist, or we'd sleep until the standby's next + * status message. + */ + if (wait_event == WAIT_EVENT_WAL_SENDER_MAIN && WalSndCaughtUp && + !streamingDoneSending && !sendTimeLineIsHistoric && + !pq_is_send_pending()) + { + XLogRecPtr flushPtr; + + flushPtr = am_cascading_walsender ? + GetStandbyFlushRecPtr(NULL) : GetFlushRecPtr(NULL); + if (flushPtr > sentPtr) + { + ConditionVariableCancelSleep(); + return; + } + } + } else if (MyWalSnd->kind == REPLICATION_KIND_LOGICAL) ConditionVariablePrepareToSleep(&WalSndCtl->wal_replay_cv); -- 2.50.1 (Apple Git-155)