From a349b63467ddab60c7aadb8a2f1f5264efe5d165 Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Fri, 28 Feb 2025 11:18:19 +0300
Subject: [PATCH v3] Limit AbsorbSyncRequests to 1Gb at once.

---
 src/backend/postmaster/checkpointer.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index 7acbbd3e26..3ca4f1fb68 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -1339,8 +1339,12 @@ AbsorbSyncRequests(void)
 	 * memory).  This is because the system cannot run safely if we are unable
 	 * to fsync what we have been told to fsync.  Fortunately, the hashtable
 	 * is so small that the problem is quite unlikely to arise in practice.
+	 *
+	 * Note: we could not palloc more than 1Gb of memory, thus make sure that
+	 * the maximum number of elements will fit in the requests buffer.
 	 */
-	n = CheckpointerShmem->num_requests;
+	n = Min(CheckpointerShmem->num_requests,
+			MaxAllocSize / sizeof(CheckpointerRequest));
 	if (n > 0)
 	{
 		requests = (CheckpointerRequest *) palloc(n * sizeof(CheckpointerRequest));
@@ -1349,7 +1353,11 @@ AbsorbSyncRequests(void)
 
 	START_CRIT_SECTION();
 
-	CheckpointerShmem->num_requests = 0;
+	CheckpointerShmem->num_requests -= n;
+
+	memmove(CheckpointerShmem->requests,
+			CheckpointerShmem->requests + n,
+			CheckpointerShmem->num_requests * sizeof(CheckpointerRequest));
 
 	LWLockRelease(CheckpointerCommLock);
 
-- 
2.48.1

