From 1bfa38c2c2033d356d4129e2d8eb8f1150e0d7ad Mon Sep 17 00:00:00 2001 From: Shihao Date: Fri, 25 Sep 2026 09:53:23 -0400 Subject: [PATCH v2 2/2] Clear waitStart when the lock is granted before it is set A waiter joins the wait queue and releases the partition lock before it stores waitStart. That happens in ProcSleep(), or in ResolveRecoveryConflictWithLock() for the startup process. If ProcWakeup() grants the lock in between, it clears waitStart first and the waiter stores its value afterwards. Nothing clears it after that. A regular backend overwrites the value at its next lock wait, so pg_locks shows the old start time only at the very start of that wait, as with the previous commit. The startup process stores waitStart only when it reads zero, so there pg_locks shows the old start time for the whole next wait. Fix by clearing waitStart at the end of ProcSleep() and in LockErrorCleanup(). The latter covers a cancel that arrives after the grant, where ProcSleep() errors out before its end. Reported-by: Fujii Masao Discussion: https://postgr.es/m/CAGRkXqQLxZBr-ouVrtaX2utMggi4+TiVMbgH04b_0JLgKryxbA@mail.gmail.com --- src/backend/storage/lmgr/proc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 91fe2766640..f93203916c1 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -871,6 +871,9 @@ LockErrorCleanup(void) GrantAwaitedLock(); } + /* Clear waitStart, for the same reason as at the end of ProcSleep() */ + pg_atomic_write_u64(&MyProc->waitStart, 0); + ResetAwaitedLock(); LWLockRelease(partitionLock); @@ -1744,6 +1747,13 @@ ProcSleep(LOCALLOCK *locallock) } } while (myWaitStatus == PROC_WAIT_STATUS_WAITING); + /* + * The wait is over, so clear waitStart. ProcWakeup() clears it too, but + * it can run before we set waitStart, and then our value would be left + * behind. + */ + pg_atomic_write_u64(&MyProc->waitStart, 0); + /* * Disable the timers, if they are still running. As in LockErrorCleanup, * we must preserve the LOCK_TIMEOUT indicator flag: if a lock timeout has -- 2.37.1 (Apple Git-137.1)