recovery_conflict_lock_deadlock_v1.patch

text/plain

Filename: recovery_conflict_lock_deadlock_v1.patch
Type: text/plain
Part: 0
Message: Deadlock between backend and recovery may not be detected

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: unified
Series: patch v1
File+
src/backend/storage/ipc/standby.c 15 6
src/backend/tcop/postgres.c 4 0
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 4ea3cf1f5c..c398f9a3a5 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -407,7 +407,7 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag)
 
 	ltime = GetStandbyLimitTime();
 
-	if (GetCurrentTimestamp() >= ltime)
+	if (GetCurrentTimestamp() >= ltime && ltime > 0)
 	{
 		/*
 		 * We're already behind, so clear a path as quickly as possible.
@@ -431,12 +431,21 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag)
 		/*
 		 * Wait (or wait again) until ltime
 		 */
-		EnableTimeoutParams timeouts[1];
+		EnableTimeoutParams timeouts[2];
+		int		i = 0;
 
-		timeouts[0].id = STANDBY_LOCK_TIMEOUT;
-		timeouts[0].type = TMPARAM_AT;
-		timeouts[0].fin_time = ltime;
-		enable_timeouts(timeouts, 1);
+		if (ltime > 0)
+		{
+			timeouts[i].id = STANDBY_LOCK_TIMEOUT;
+			timeouts[i].type = TMPARAM_AT;
+			timeouts[i].fin_time = ltime;
+			i++;
+		}
+		timeouts[i].id = STANDBY_DEADLOCK_TIMEOUT;
+		timeouts[i].type = TMPARAM_AFTER;
+		timeouts[i].delay_ms = DeadlockTimeout;
+		i++;
+		enable_timeouts(timeouts, i);
 	}
 
 	/* Wait to be signaled by the release of the Relation Lock */
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 3679799e50..3717381a6a 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2923,7 +2923,11 @@ RecoveryConflictInterrupt(ProcSignalReason reason)
 				 * more to do.
 				 */
 				if (!HoldingBufferPinThatDelaysRecovery())
+				{
+					if (reason == PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK)
+						CheckDeadLockAlert();
 					return;
+				}
 
 				MyProc->recoveryConflictPending = true;