From b85f9c00fb8822eb2142c347ce529f651dbef178 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Sat, 20 Jun 2026 15:00:40 +0900 Subject: [PATCH] Make StandbyAcquireAccessExclusiveLock() more resilent with OOMs In StandbyReleaseXidEntryLocks, a failure in acquiring a lock with LockAcquire() due to an out-of-memory problem would lead to an inconsistency with the lock state cached in the startup process, impacting the list of RecoveryLockXidEntrys. The code is updated here so as the cached state is updated once the lock is acquired. This problem is unlikely going to happen in practice. Even if it were to show up, it would translate to a LOG message for non-assert builds (assertion failure otherwise), so no backpatch is done. This commit is in the same spirit as 29fb598b9cad, with a problem emulated by injecting random failures for allocations. Reported-by: Alexander Lakhin Author: Matthias van de Meent Discussion: https://postgr.es/m/e77acaac-a1b3-40b3-99ee-5769b4e453e4@gmail.com --- src/backend/storage/ipc/standby.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index de9092fdf5b..7f011e04990 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -1019,14 +1019,14 @@ 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, as it is new, link it into the XID's list. */ + lockentry->next = xidentry->head; + xidentry->head = lockentry; } }