]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Make StandbyAcquireAccessExclusiveLock() more resilent with OOMs
authorMichael Paquier <michael@paquier.xyz>
Sat, 20 Jun 2026 06:00:40 +0000 (15:00 +0900)
committerMichael Paquier <michael@paquier.xyz>
Sat, 20 Jun 2026 06:00:40 +0000 (15:00 +0900)
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 <exclusion@gmail.com>
Author: Matthias van de Meent <boekewurm+postgres@gmail.com>
Discussion: https://postgr.es/m/e77acaac-a1b3-40b3-99ee-5769b4e453e4@gmail.com

src/backend/storage/ipc/standby.c

index de9092fdf5bc9c5d1f83e3c284fdba9a63d58206..7f011e049909bf2b068c0920b93d725a7c77c5dd 100644 (file)
@@ -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;
        }
 }