v2-0001-Prevent-repeated-deadlock-check-signals-in-standb.patch
application/octet-stream
Filename: v2-0001-Prevent-repeated-deadlock-check-signals-in-standb.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0001
Subject: Prevent repeated deadlock-check signals in standby buffer pin waits
| File | + | − |
|---|---|---|
| src/backend/storage/ipc/standby.c | 12 | 9 |
From e70a2fc74a63d4c1e3d1277e27a37b1e26710fff Mon Sep 17 00:00:00 2001
From: JoongHyuk Shin <sjh910805@gmail.com>
Date: Fri, 17 Apr 2026 16:58:31 +0900
Subject: [PATCH v2] Prevent repeated deadlock-check signals in standby buffer
pin waits
After sending RECOVERY_CONFLICT_BUFFERPIN_DEADLOCK, the startup process
returned without waiting, so the caller's loop would fire another
deadlock_timeout and re-send the signal every interval. This added
unnecessary overhead in both the startup process and backends.
Fix by adding a ProcWaitForSignal() call after the deadlock-check
signal, mirroring the approach already used in the lock-conflict path
(commit 8900b5a9d59a). This ensures the signal is sent at most once
per deadlock_timeout period rather than repeatedly.
Additionally, reset got_standby_delay_timeout to false before enabling
STANDBY_TIMEOUT, for symmetry with the existing got_standby_deadlock_timeout
reset.
Remove the XXX comment that noted this problem.
---
src/backend/storage/ipc/standby.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 29af7733948..0dba1fb4289 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -818,6 +818,7 @@ ResolveRecoveryConflictWithBufferPin(void)
if (ltime != 0)
{
+ got_standby_delay_timeout = false;
timeouts[cnt].id = STANDBY_TIMEOUT;
timeouts[cnt].type = TMPARAM_AT;
timeouts[cnt].fin_time = ltime;
@@ -851,17 +852,19 @@ ResolveRecoveryConflictWithBufferPin(void)
/*
* Send out a request for hot-standby backends to check themselves for
* deadlocks.
- *
- * XXX The subsequent ResolveRecoveryConflictWithBufferPin() will wait
- * to be signaled by UnpinBuffer() again and send a request for
- * deadlocks check if deadlock_timeout happens. This causes the
- * request to continue to be sent every deadlock_timeout until the
- * buffer is unpinned or ltime is reached. This would increase the
- * workload in the startup process and backends. In practice it may
- * not be so harmful because the period that the buffer is kept pinned
- * is basically no so long. But we should fix this?
*/
SendRecoveryConflictWithBufferPin(RECOVERY_CONFLICT_BUFFERPIN_DEADLOCK);
+
+ /*
+ * Wait here to be signaled by UnpinBuffer(), to prevent the
+ * subsequent ResolveRecoveryConflictWithBufferPin() call (from the
+ * caller's loop) from firing another deadlock_timeout and re-sending
+ * the deadlock-check signal. Without this, the signal would be sent
+ * every deadlock_timeout interval until the buffer is unpinned or
+ * ltime is reached.
+ */
+ got_standby_deadlock_timeout = false;
+ ProcWaitForSignal(WAIT_EVENT_BUFFER_CLEANUP);
}
/*
--
2.52.0