diff options
author | Nathan Bossart <nathan@postgresql.org> | 2025-09-18 09:55:39 -0500 |
---|---|---|
committer | Nathan Bossart <nathan@postgresql.org> | 2025-09-18 09:55:39 -0500 |
commit | c3cc2ab87d72a1ce17a7f574756158479ef32f20 (patch) | |
tree | acf6230c4e927fff1f4ba3ce662f650dc2239439 | |
parent | 2e66cae935c2e0f7ce9bab6b65ddeb7806f4de7c (diff) |
Fix re-initialization of LWLock-related shared memory.
When shared memory is re-initialized after a crash, the named
LWLock tranche request array that was copied to shared memory will
no longer be accessible. To fix, save the pointer to the original
array in postmaster's local memory, and switch to it when
re-initializing the LWLock-related shared memory.
Oversight in commit ed1aad15e0. Per buildfarm member batta.
Reported-by: Michael Paquier <michael@paquier.xyz>
Reported-by: Alexander Lakhin <exclusion@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/aMoejB3iTWy1SxfF%40paquier.xyz
Discussion: https://postgr.es/m/f8ca018f-3479-49f6-a92c-e31db9f849d7%40gmail.com
-rw-r--r-- | src/backend/storage/lmgr/lwlock.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index 46c82c63ca5..b017880f5e4 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -192,6 +192,9 @@ typedef struct NamedLWLockTrancheRequest int NamedLWLockTrancheRequests = 0; NamedLWLockTrancheRequest *NamedLWLockTrancheRequestArray = NULL; +/* postmaster's local copy of the request array */ +static NamedLWLockTrancheRequest *LocalNamedLWLockTrancheRequestArray = NULL; + /* shared memory counter of registered tranches */ int *LWLockCounter = NULL; @@ -396,6 +399,15 @@ LWLockShmemSize(void) Size size; int numLocks = NUM_FIXED_LWLOCKS; + /* + * If re-initializing shared memory, the request array will no longer be + * accessible, so switch to the copy in postmaster's local memory. We'll + * copy it back into shared memory later when CreateLWLocks() is called + * again. + */ + if (LocalNamedLWLockTrancheRequestArray) + NamedLWLockTrancheRequestArray = LocalNamedLWLockTrancheRequestArray; + /* Calculate total number of locks needed in the main array. */ numLocks += NumLWLocksForNamedTranches(); @@ -457,9 +469,15 @@ CreateLWLocks(void) */ if (NamedLWLockTrancheRequests > 0) { + /* + * Save the pointer to the request array in postmaster's local + * memory. We'll need it if we ever need to re-initialize shared + * memory after a crash. + */ + LocalNamedLWLockTrancheRequestArray = NamedLWLockTrancheRequestArray; + memcpy(ptr, NamedLWLockTrancheRequestArray, NamedLWLockTrancheRequests * sizeof(NamedLWLockTrancheRequest)); - pfree(NamedLWLockTrancheRequestArray); NamedLWLockTrancheRequestArray = (NamedLWLockTrancheRequest *) ptr; ptr += NamedLWLockTrancheRequests * sizeof(NamedLWLockTrancheRequest); } |