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
Message: RE: Connection limits/permissions, slotsync workers, etc

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