Back-patch b1ffe3ff into REL_13_STABLE.
authorThomas Munro <[email protected]>
Wed, 8 Jan 2025 21:03:10 +0000 (10:03 +1300)
committerThomas Munro <[email protected]>
Wed, 8 Jan 2025 21:14:11 +0000 (10:14 +1300)
This is a cherry pick of 4c8e00ae from the 14 branch into the 13 branch.

It avoids an assertion failure when ForwardSyncRequest() tries to
allocate memory while trying to compact the queue, if run in a critical
section.  RelationTruncate() gained a critical section in 38c579b0, and
could fail in that way in the 13 branch.

b1ffe3ff originally fixed the same problem with TruncateMultiXact(), but
for that case it only needed to go back as far as 14, where SLRUs
started using the sync request queue.  It also fixed a related deadlock
risk that doesn't apply in this case (this case doesn't wait), but it
might exist in theory and it doesn't hurt to keep the code the same as
later branches.

Author: Heikki Linnakangas <[email protected]> (original commit)
Reviewed-by: Michael Paquier <[email protected]> (in this new context)
Reported-by: Yura Sokolov <[email protected]>
Discussion: https://postgr.es/m/f98aaa79-80b5-47c9-832a-31416a3a528b%40postgrespro.ru

src/backend/access/transam/xlog.c
src/backend/postmaster/checkpointer.c

index 1fa15a58be39eda1015954c61cdc4f8c0063f8b2..3277a1cbe68326f74d0ed9c649cd58e09055cfd8 100644 (file)
@@ -9139,6 +9139,12 @@ CreateCheckPoint(int flags)
    {
        do
        {
+           /*
+            * Keep absorbing fsync requests while we wait. There could even
+            * be a deadlock if we don't, if the process that prevents the
+            * checkpoint is trying to add a request to the queue.
+            */
+           AbsorbSyncRequests();
            pg_usleep(10000L);  /* wait for 10 msec */
        } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids));
    }
@@ -9151,6 +9157,7 @@ CreateCheckPoint(int flags)
    {
        do
        {
+           AbsorbSyncRequests();
            pg_usleep(10000L);  /* wait for 10 msec */
        } while (HaveVirtualXIDsDelayingChkptEnd(vxids, nvxids));
    }
index 624a3238b804cd64aab3f8b2d1da6440b88daf2a..9b2f776579b17b98b21c4a1298e763d7721e670e 100644 (file)
@@ -1144,6 +1144,10 @@ CompactCheckpointerRequestQueue(void)
    /* must hold CheckpointerCommLock in exclusive mode */
    Assert(LWLockHeldByMe(CheckpointerCommLock));
 
+   /* Avoid memory allocations in a critical section. */
+   if (CritSectionCount > 0)
+       return false;
+
    /* Initialize skip_slot array */
    skip_slot = palloc0(sizeof(bool) * CheckpointerShmem->num_requests);