From 71a5f6bde59d6dd31f5915a089154d6acd09eea4 Mon Sep 17 00:00:00 2001 From: Hou Zhijie 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