Limit checkpointer requests queue size REL_14_STABLE github/REL_14_STABLE
authorAlexander Korotkov <akorotkov@postgresql.org>
Sun, 27 Jul 2025 12:10:01 +0000 (15:10 +0300)
committerAlexander Korotkov <akorotkov@postgresql.org>
Sun, 27 Jul 2025 12:10:31 +0000 (15:10 +0300)
If the number of sync requests is big enough, the palloc() call in
AbsorbSyncRequests() will attempt to allocate more than 1 GB of memory,
resulting in failure.  This can lead to an infinite loop in the checkpointer
process, as it repeatedly fails to absorb the pending requests.

This commit limits the checkpointer requests queue size to 10M items. In
addition to preventing the palloc() failure, this change helps to avoid long
queue processing time.

Also, this commit is for backpathing only.  The master branch receives
a more invasive yet comprehensive fix for this problem.

Discussion: http://postgr.es/m/db4534f83a22a29ab5ee2566ad86ca92%40postgrespro.ru
Backpatch-through: 13

src/backend/postmaster/checkpointer.c

index 3b1049faef64a996c9f0a1aa77b70c95442b5040..17a068b27b82673d88bccfeb7bc8bd05f8a97e96 100644 (file)
@@ -140,6 +140,9 @@ static CheckpointerShmemStruct *CheckpointerShmem;
 /* interval for calling AbsorbSyncRequests in CheckpointWriteDelay */
 #define WRITES_PER_ABSORB      1000
 
+/* Max number of requests the checkpointer request queue can hold */
+#define MAX_CHECKPOINT_REQUESTS 10000000
+
 /*
  * GUC parameters
  */
@@ -906,7 +909,7 @@ CheckpointerShmemInit(void)
         */
        MemSet(CheckpointerShmem, 0, size);
        SpinLockInit(&CheckpointerShmem->ckpt_lck);
-       CheckpointerShmem->max_requests = NBuffers;
+       CheckpointerShmem->max_requests = Min(NBuffers, MAX_CHECKPOINT_REQUESTS);
        ConditionVariableInit(&CheckpointerShmem->start_cv);
        ConditionVariableInit(&CheckpointerShmem->done_cv);
    }