From 78c54247448fa044e9164371f221e3ccf31ed9e9 Mon Sep 17 00:00:00 2001
From: alterego655 <824662526@qq.com>
Date: Fri, 24 Jul 2026 16:34:29 +0800
Subject: [PATCH v2 3/5] Avoid unnecessary WaitLSNLock acquisition after wakeup

WaitLSNWakeup() removes a satisfied waiter from the heap and clears its
inHeap flag before waking it.  When the waiter resumed,
deleteLSNWaiter() acquired WaitLSNLock exclusively only to confirm that
the entry had already been removed.  Concurrently awakened waiters
therefore serialized on unnecessary lock acquisitions.

Check inHeap before acquiring the lock.  An unlocked false value is safe
because only the owning backend can set the flag; a stale true value
still reaches the existing locked recheck.
---
 src/backend/access/transam/xlogwait.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c
index aa6e549ea63..fd6599b4274 100644
--- a/src/backend/access/transam/xlogwait.c
+++ b/src/backend/access/transam/xlogwait.c
@@ -252,6 +252,9 @@ deleteLSNWaiter(WaitLSNType lsnType)
 
 	Assert(i >= 0 && i < WAIT_LSN_TYPE_COUNT);
 
+	if (!procInfo->inHeap)
+		return;
+
 	LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE);
 
 	Assert(procInfo->lsnType == lsnType);
-- 
2.51.0

