v1-0001-Reserve-a-dedicated-PGPROC-slot-for-slotsync-work.patch
application/octet-stream
Filename: v1-0001-Reserve-a-dedicated-PGPROC-slot-for-slotsync-work.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v1-0001
Subject: Reserve a dedicated PGPROC slot for slotsync worker
| File | + | − |
|---|---|---|
| src/backend/storage/lmgr/proc.c | 14 | 5 |
| src/backend/utils/init/postinit.c | 5 | 2 |
| src/include/storage/proc.h | 8 | 0 |
From 71a5f6bde59d6dd31f5915a089154d6acd09eea4 Mon Sep 17 00:00:00 2001
From: Hou Zhijie <houzj.fnst@cn.fujitsu.com>
Date: Fri, 27 Dec 2024 14:25:51 +0800
Subject: [PATCH v1] Reserve a dedicated PGPROC slot for slotsync worker
Currently, a slot sync worker cannot start when user backends have reached
the max_connections limit. This occurs because the slot sync worker competes for
an entry within the max_connections allocation. To resolve this, it would be
better to provide a dedicated PGPROC slot for the slot sync worker, independent
of max_connections, similar to how autovacuum launcher/workers and WAL sender
processes are handled. This patch implements this solution to resolve the
issue.
---
src/backend/storage/lmgr/proc.c | 19 ++++++++++++++-----
src/backend/utils/init/postinit.c | 7 +++++--
src/include/storage/proc.h | 8 ++++++++
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 720ef99ee8..9cb1229286 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -189,6 +189,7 @@ InitProcGlobal(void)
dlist_init(&ProcGlobal->autovacFreeProcs);
dlist_init(&ProcGlobal->bgworkerFreeProcs);
dlist_init(&ProcGlobal->walsenderFreeProcs);
+ dlist_init(&ProcGlobal->slotsyncFreeProcs);
ProcGlobal->startupBufferPinWaitBufId = -1;
ProcGlobal->walwriterProc = INVALID_PROC_NUMBER;
ProcGlobal->checkpointerProc = INVALID_PROC_NUMBER;
@@ -198,10 +199,10 @@ InitProcGlobal(void)
/*
* Create and initialize all the PGPROC structures we'll need. There are
* five separate consumers: (1) normal backends, (2) autovacuum workers
- * and the autovacuum launcher, (3) background workers, (4) auxiliary
- * processes, and (5) prepared transactions. Each PGPROC structure is
- * dedicated to exactly one of these purposes, and they do not move
- * between groups.
+ * and the autovacuum launcher, (3) background workers, (4) the slot sync
+ * worker, (5) auxiliary processes, and (6) prepared transactions. Each
+ * PGPROC structure is dedicated to exactly one of these purposes, and
+ * they do not move between groups.
*/
procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
@@ -294,12 +295,18 @@ InitProcGlobal(void)
dlist_push_tail(&ProcGlobal->bgworkerFreeProcs, &proc->links);
proc->procgloballist = &ProcGlobal->bgworkerFreeProcs;
}
- else if (i < MaxBackends)
+ else if (i < MaxConnections + autovacuum_max_workers + 1 + max_worker_processes + max_wal_senders)
{
/* PGPROC for walsender, add to walsenderFreeProcs list */
dlist_push_tail(&ProcGlobal->walsenderFreeProcs, &proc->links);
proc->procgloballist = &ProcGlobal->walsenderFreeProcs;
}
+ else if (i < MaxBackends)
+ {
+ /* PGPROC for slot sync worker, add to slotsyncFreeProcs list */
+ dlist_push_tail(&ProcGlobal->slotsyncFreeProcs, &proc->links);
+ proc->procgloballist = &ProcGlobal->slotsyncFreeProcs;
+ }
/* Initialize myProcLocks[] shared memory queues. */
for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
@@ -365,6 +372,8 @@ InitProcess(void)
procgloballist = &ProcGlobal->bgworkerFreeProcs;
else if (AmWalSenderProcess())
procgloballist = &ProcGlobal->walsenderFreeProcs;
+ else if (AmLogicalSlotSyncWorkerProcess())
+ procgloballist = &ProcGlobal->slotsyncFreeProcs;
else
procgloballist = &ProcGlobal->freeProcs;
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 5b657a3f13..2c2f06e597 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -544,9 +544,12 @@ InitializeMaxBackends(void)
{
Assert(MaxBackends == 0);
- /* the extra unit accounts for the autovacuum launcher */
+ /*
+ * The extra units account for the autovacuum launcher and the slot sync
+ * worker.
+ */
MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
- max_worker_processes + max_wal_senders;
+ max_worker_processes + max_wal_senders + 1;
if (MaxBackends > MAX_BACKENDS)
ereport(ERROR,
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 5a3dd5d2d4..d0b197e148 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -414,6 +414,14 @@ typedef struct PROC_HDR
dlist_head bgworkerFreeProcs;
/* Head of list of walsender free PGPROC structures */
dlist_head walsenderFreeProcs;
+
+ /*
+ * Head of list of slot sync worker free PGPROC structures. Only one slot
+ * sync worker is supported for now, but storing it in a list format to be
+ * consistent and to make it easier to support multiple workers in the
+ * future.
+ */
+ dlist_head slotsyncFreeProcs;
/* First pgproc waiting for group XID clear */
pg_atomic_uint32 procArrayGroupFirst;
/* First pgproc waiting for group transaction status update */
--
2.31.1