v1-0001-AbsorbSyncRequests-incrementally-instead-of-doing.patch
application/octet-stream
Filename: v1-0001-AbsorbSyncRequests-incrementally-instead-of-doing.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v1-0001
Subject: AbsorbSyncRequests incrementally, instead of doing it for all requests at once.
| File | + | − |
|---|---|---|
| src/backend/postmaster/checkpointer.c | 37 | 22 |
From 6c11de18f460232f7064a56aff3413406c824ff3 Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Thu, 27 Feb 2025 12:59:51 +0300
Subject: [PATCH v1] AbsorbSyncRequests incrementally, instead of doing it for
all requests at once.
---
src/backend/postmaster/checkpointer.c | 59 +++++++++++++++++----------
1 file changed, 37 insertions(+), 22 deletions(-)
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index 7acbbd3e267..a4c6544e13b 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -1321,42 +1321,57 @@ CompactCheckpointerRequestQueue(void)
void
AbsorbSyncRequests(void)
{
- CheckpointerRequest *requests = NULL;
- CheckpointerRequest *request;
- int n;
+ CheckpointerRequest *requests = NULL;
+ int num_requests,
+ max_requests;
if (!AmCheckpointerProcess())
return;
LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE);
+ num_requests = CheckpointerShmem->num_requests;
/*
- * We try to avoid holding the lock for a long time by copying the request
- * array, and processing the requests after releasing the lock.
- *
- * Once we have cleared the requests from shared memory, we have to PANIC
- * if we then fail to absorb them (eg, because our hashtable runs out of
- * 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: this can be chosen arbitrarily, stick for 1Gb for now.
*/
- n = CheckpointerShmem->num_requests;
- if (n > 0)
+ max_requests = MaxAllocSize / sizeof(CheckpointerRequest);
+
+ for (int i = 0; i < num_requests; i += max_requests)
{
- requests = (CheckpointerRequest *) palloc(n * sizeof(CheckpointerRequest));
- memcpy(requests, CheckpointerShmem->requests, n * sizeof(CheckpointerRequest));
- }
+ Size n = (num_requests - i >= max_requests) ? max_requests :
+ num_requests - i;
- START_CRIT_SECTION();
+ if (!requests)
+ requests = palloc(n * sizeof(CheckpointerRequest));
- CheckpointerShmem->num_requests = 0;
+ memcpy(requests, CheckpointerShmem->requests + i,
+ n * sizeof(CheckpointerRequest));
- LWLockRelease(CheckpointerCommLock);
+ LWLockRelease(CheckpointerCommLock);
+
+ START_CRIT_SECTION();
- for (request = requests; n > 0; request++, n--)
- RememberSyncRequest(&request->ftag, request->type);
+ /*
+ * We try to avoid holding the lock for a long time by copying the
+ * request array, and processing the requests after releasing the lock.
+ *
+ * Once we have cleared the requests from shared memory, we have to
+ * PANIC if we then fail to absorb them (eg, because our hashtable runs
+ * out of 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.
+ */
+ for (int j = 0; j < n; j++)
+ RememberSyncRequest(&requests[j].ftag, requests[j].type);
+
+ END_CRIT_SECTION();
- END_CRIT_SECTION();
+ LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE);
+ }
+
+ CheckpointerShmem->num_requests = 0;
+ LWLockRelease(CheckpointerCommLock);
if (requests)
pfree(requests);
--
2.43.0