v3-0001-IPC-standby-keep-better-track-of-taken-locks.patch

application/octet-stream

Filename: v3-0001-IPC-standby-keep-better-track-of-taken-locks.patch
Type: application/octet-stream
Part: 0
Message: Re: Unexpected behavior after OOM errors

Patch

Format: format-patch
Series: patch v3-0001
Subject: IPC/standby: keep better track of taken locks
File+
src/backend/storage/ipc/standby.c 11 5
From f260f9e275effca846361f213e0f08c3865394b0 Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <boekewurm+postgres@gmail.com>
Date: Thu, 18 Jun 2026 17:06:55 +0200
Subject: [PATCH v3] IPC/standby: keep better track of taken locks

Previously, a lock that wasn't taken (e.g. due to a lack of available
locks) could cause all kinds of havoc in recovery-local lock state.
Now, we're more robust against that, by only registering the relation
lock once the lock is taken:  If LockAcquire() fails, the failed lock
won't be present in the xidentry's list.
---
 src/backend/storage/ipc/standby.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 872679ca447..0ba78bf63d6 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -1016,14 +1016,20 @@ StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
 	lockentry = hash_search(RecoveryLockHash, &key, HASH_ENTER, &found);
 	if (!found)
 	{
-		/* It's new, so link it into the XID's list ... */
-		lockentry->next = xidentry->head;
-		xidentry->head = lockentry;
-
-		/* ... and acquire the lock locally. */
+		/* First, acquire the lock ... */
 		SET_LOCKTAG_RELATION(locktag, dbOid, relOid);
 
 		(void) LockAcquire(&locktag, AccessExclusiveLock, true, false);
+
+		/*
+		 * ... and then, link it into the local state.
+		 *
+		 * This avoids issues in StandbyReleaseXidEntryLocks when LockAcquire
+		 * fails to acquire a lock (e.g. due to lock entry exhaustion); in that
+		 * case the xidentry isn't inconsistent.
+		 */
+		lockentry->next = xidentry->head;
+		xidentry->head = lockentry;
 	}
 }
 
-- 
2.50.1 (Apple Git-155)