Re: Connection limits/permissions, slotsync workers, etc - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Connection limits/permissions, slotsync workers, etc
Date
Msg-id 2279105.1735320651@sss.pgh.pa.us
Whole thread Raw
In response to Connection limits/permissions, slotsync workers, etc  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Connection limits/permissions, slotsync workers, etc
RE: Connection limits/permissions, slotsync workers, etc
List pgsql-hackers
"Zhijie Hou (Fujitsu)" <houzj.fnst@fujitsu.com> writes:
> On Thursday, December 26, 2024 3:50 AM Tom Lane <tgl@sss.pgh.pa.us>
>> I wonder if the AV launcher and slotsync worker could be reclassified as "auxiliary
>> processes" instead of being their own weird animal.

> It appears that the current aux processes do not run transactions as stated in the
> comments[1], so we may need to somehow release this restriction to achieve the
> goal.

Ah, right, I'd forgotten about that restriction.  I agree that
removing it wouldn't be very reasonable.  However, I still would
rather avoid making the slotsync worker be its very own special
snowflake, because that offers no support for the next person
who wants to invent a new sort of specialized transaction-capable
process.

Attached is an alternative proposal that groups the autovac launcher
and slotsync worker into a new category of "special workers" (better
name welcome).  I chose to put them into the existing autovacFreeProcs
freelist, partly because the autovac launcher lives there already
but mostly because I don't want to add another freelist in a patch
we need to put into v17.  (As written, your patch is an ABI break.
It'd probably be safe to add a new freelist at the end of the struct
in v17, but I'm a little shy about that in view of recent bugs.  In
any case, a freelist having at most two members seems rather silly.)

I was amused but not terribly surprised to notice that the comments
in InitProcGlobal were *already* out of date, in that they didn't
account for the walsender PGPROC pool.  We have a remarkably bad
track record for updating comments that are more than about two
lines away from the code they describe :-(

Thoughts?

            regards, tom lane

diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 720ef99ee8..10d4fb4ea1 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -197,11 +197,12 @@ 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.
+     * six separate consumers: (1) normal backends, (2) autovacuum workers and
+     * special workers, (3) background workers, (4) walsenders, (5) auxiliary
+     * processes, and (6) prepared transactions.  (For largely-historical
+     * reasons, we combine autovacuum and special workers into one category
+     * with a single freelist.)  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));
@@ -269,12 +270,13 @@ InitProcGlobal(void)
         }

         /*
-         * Newly created PGPROCs for normal backends, autovacuum and bgworkers
-         * must be queued up on the appropriate free list.  Because there can
-         * only ever be a small, fixed number of auxiliary processes, no free
-         * list is used in that case; InitAuxiliaryProcess() instead uses a
-         * linear search.   PGPROCs for prepared transactions are added to a
-         * free list by TwoPhaseShmemInit().
+         * Newly created PGPROCs for normal backends, autovacuum workers,
+         * special workers, bgworkers, and walsenders must be queued up on the
+         * appropriate free list.  Because there can only ever be a small,
+         * fixed number of auxiliary processes, no free list is used in that
+         * case; InitAuxiliaryProcess() instead uses a linear search.  PGPROCs
+         * for prepared transactions are added to a free list by
+         * TwoPhaseShmemInit().
          */
         if (i < MaxConnections)
         {
@@ -282,13 +284,13 @@ InitProcGlobal(void)
             dlist_push_tail(&ProcGlobal->freeProcs, &proc->links);
             proc->procgloballist = &ProcGlobal->freeProcs;
         }
-        else if (i < MaxConnections + autovacuum_max_workers + 1)
+        else if (i < MaxConnections + autovacuum_max_workers + NUM_SPECIAL_WORKER_PROCS)
         {
-            /* PGPROC for AV launcher/worker, add to autovacFreeProcs list */
+            /* PGPROC for AV or special worker, add to autovacFreeProcs list */
             dlist_push_tail(&ProcGlobal->autovacFreeProcs, &proc->links);
             proc->procgloballist = &ProcGlobal->autovacFreeProcs;
         }
-        else if (i < MaxConnections + autovacuum_max_workers + 1 + max_worker_processes)
+        else if (i < MaxConnections + autovacuum_max_workers + NUM_SPECIAL_WORKER_PROCS + max_worker_processes)
         {
             /* PGPROC for bgworker, add to bgworkerFreeProcs list */
             dlist_push_tail(&ProcGlobal->bgworkerFreeProcs, &proc->links);
@@ -358,8 +360,11 @@ InitProcess(void)
     if (IsUnderPostmaster)
         RegisterPostmasterChildActive();

-    /* Decide which list should supply our PGPROC. */
-    if (AmAutoVacuumLauncherProcess() || AmAutoVacuumWorkerProcess())
+    /*
+     * Decide which list should supply our PGPROC.  This logic must match the
+     * way the freelists were constructed in InitProcGlobal().
+     */
+    if (AmAutoVacuumWorkerProcess() || AmSpecialWorkerProcess())
         procgloballist = &ProcGlobal->autovacFreeProcs;
     else if (AmBackgroundWorkerProcess())
         procgloballist = &ProcGlobal->bgworkerFreeProcs;
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 770ab6906e..9731de5781 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -544,9 +544,9 @@ InitializeMaxBackends(void)
 {
     Assert(MaxBackends == 0);

-    /* the extra unit accounts for the autovacuum launcher */
-    MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
-        max_worker_processes + max_wal_senders;
+    /* Note that this does not include "auxiliary" processes */
+    MaxBackends = MaxConnections + autovacuum_max_workers +
+        max_worker_processes + max_wal_senders + NUM_SPECIAL_WORKER_PROCS;

     if (MaxBackends > MAX_BACKENDS)
         ereport(ERROR,
@@ -555,7 +555,7 @@ InitializeMaxBackends(void)
                  errdetail("\"max_connections\" (%d) plus \"autovacuum_max_workers\" (%d) plus
\"max_worker_processes\"(%d) plus \"max_wal_senders\" (%d) must be less than %d.", 
                            MaxConnections, autovacuum_max_workers,
                            max_worker_processes, max_wal_senders,
-                           MAX_BACKENDS)));
+                           MAX_BACKENDS - (NUM_SPECIAL_WORKER_PROCS - 1))));
 }

 /*
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 3f97fcef80..d07181f932 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -350,8 +350,9 @@ typedef enum BackendType

     /*
      * Auxiliary processes. These have PGPROC entries, but they are not
-     * attached to any particular database. There can be only one of each of
-     * these running at a time.
+     * attached to any particular database, and cannot run transactions or
+     * even take heavyweight locks. There can be only one of each of these
+     * running at a time.
      *
      * If you modify these, make sure to update NUM_AUXILIARY_PROCS and the
      * glossary in the docs.
@@ -388,6 +389,10 @@ extern PGDLLIMPORT BackendType MyBackendType;
 #define AmWalSummarizerProcess()    (MyBackendType == B_WAL_SUMMARIZER)
 #define AmWalWriterProcess()        (MyBackendType == B_WAL_WRITER)

+#define AmSpecialWorkerProcess() \
+    (AmAutoVacuumLauncherProcess() || \
+     AmLogicalSlotSyncWorkerProcess())
+
 extern const char *GetBackendTypeDesc(BackendType backendType);

 extern void SetDatabasePath(const char *path);
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 5a3dd5d2d4..14e34d4e93 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -408,7 +408,7 @@ typedef struct PROC_HDR
     uint32        allProcCount;
     /* Head of list of free PGPROC structures */
     dlist_head    freeProcs;
-    /* Head of list of autovacuum's free PGPROC structures */
+    /* Head of list of autovacuum & special worker free PGPROC structures */
     dlist_head    autovacFreeProcs;
     /* Head of list of bgworker free PGPROC structures */
     dlist_head    bgworkerFreeProcs;
@@ -442,9 +442,19 @@ extern PGDLLIMPORT PGPROC *PreparedXactProcs;
 #define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
 #define GetNumberFromPGProc(proc) ((proc) - &ProcGlobal->allProcs[0])

+/*
+ * We set aside some extra PGPROC structures for "special worker" processes,
+ * which are full-fledged backends (they can run transactions)
+ * but are unique animals that there's never more than one of.
+ * Currently there are two such processes: the autovacuum launcher
+ * and the slotsync worker.
+ */
+#define NUM_SPECIAL_WORKER_PROCS    2
+
 /*
  * We set aside some extra PGPROC structures for auxiliary processes,
- * ie things that aren't full-fledged backends but need shmem access.
+ * ie things that aren't full-fledged backends (they cannot run transactions
+ * or take heavyweight locks) but need shmem access.
  *
  * Background writer, checkpointer, WAL writer, WAL summarizer, and archiver
  * run during normal operation.  Startup process and WAL receiver also consume

pgsql-hackers by date:

Previous
From: Greg Sabino Mullane
Date:
Subject: Re: [PATCHES] Post-special page storage TDE support
Next
From: Jeremy Schneider
Date:
Subject: Re: RFC: Allow EXPLAIN to Output Page Fault Information