From 259615d1b03ce2f27ddd17d9210147e39cd7a4cf Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Sat, 13 Apr 2024 21:42:33 -0500
Subject: [PATCH v1 4/4] Reintroduce autovacuum_max_workers as a PGC_SIGHUP
 parameter.

---
 doc/src/sgml/config.sgml                      | 25 ++++++++++++++++++-
 doc/src/sgml/maintenance.sgml                 |  4 +--
 src/backend/postmaster/autovacuum.c           |  4 ++-
 src/backend/utils/misc/guc_tables.c           | 15 ++++++++---
 src/backend/utils/misc/postgresql.conf.sample |  3 ++-
 src/include/postmaster/autovacuum.h           |  1 +
 .../xid_wraparound/t/001_emergency_vacuum.pl  |  2 +-
 .../xid_wraparound/t/003_wraparounds.pl       |  2 +-
 8 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index b4d67a93b6..569b090593 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1914,7 +1914,7 @@ include_dir 'conf.d'
        </para>
        <para>
         Note that when autovacuum runs, up to
-        <xref linkend="guc-autovacuum-max-worker-slots"/> times this memory
+        <xref linkend="guc-autovacuum-max-workers"/> times this memory
         may be allocated, so be careful not to set the default value
         too high.  It may be useful to control for this by separately
         setting <xref linkend="guc-autovacuum-work-mem"/>.
@@ -8540,12 +8540,35 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
        <primary><varname>autovacuum_max_worker_slots</varname> configuration parameter</primary>
       </indexterm>
       </term>
+      <listitem>
+       <para>
+        Specifies the number of backend slots to reserve for autovacuum worker
+        processes.  The default is 32.  This parameter can only be set at server
+        start.
+       </para>
+       <para>
+        Note that the value of <xref linkend="guc-autovacuum-max-workers"/> is
+        silently capped to this value.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-autovacuum-max-workers" xreflabel="autovacuum_max_workers">
+      <term><varname>autovacuum_max_workers</varname> (<type>integer</type>)
+      <indexterm>
+       <primary><varname>autovacuum_max_workers</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
       <listitem>
        <para>
         Specifies the maximum number of autovacuum processes (other than the
         autovacuum launcher) that may be running at any one time.  The default
         is three.  This parameter can only be set at server start.
        </para>
+       <para>
+        Note that this value is silently capped to the value of
+        <xref linkend="guc-autovacuum-max-worker-slots"/>.
+       </para>
       </listitem>
      </varlistentry>
 
diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml
index 7b4b3f0087..2bfa05b8bc 100644
--- a/doc/src/sgml/maintenance.sgml
+++ b/doc/src/sgml/maintenance.sgml
@@ -864,9 +864,9 @@ HINT:  Execute a database-wide VACUUM in that database.
     seconds.  (Therefore, if the installation has <replaceable>N</replaceable> databases,
     a new worker will be launched every
     <varname>autovacuum_naptime</varname>/<replaceable>N</replaceable> seconds.)
-    A maximum of <xref linkend="guc-autovacuum-max-worker-slots"/> worker processes
+    A maximum of <xref linkend="guc-autovacuum-max-workers"/> worker processes
     are allowed to run at the same time. If there are more than
-    <varname>autovacuum_max_worker_slots</varname> databases to be processed,
+    <varname>autovacuum_max_workers</varname> databases to be processed,
     the next database will be processed as soon as the first worker finishes.
     Each worker process will check each table within its database and
     execute <command>VACUUM</command> and/or <command>ANALYZE</command> as needed.
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f80365faff..ed7e2b462f 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -115,6 +115,7 @@
  */
 bool		autovacuum_start_daemon = false;
 int			autovacuum_max_worker_slots;
+int			autovacuum_max_workers;
 int			autovacuum_work_mem = -1;
 int			autovacuum_naptime;
 int			autovacuum_vac_thresh;
@@ -3346,6 +3347,7 @@ static bool
 av_worker_available(void)
 {
 	const dclist_head *freelist = &AutoVacuumShmem->av_freeWorkers;
+	int			reserved_slots = autovacuum_max_worker_slots - autovacuum_max_workers;
 
-	return dclist_count(freelist) > 0;
+	return dclist_count(freelist) > Max(0, reserved_slots);
 }
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 92dea7061a..92d4d10fe9 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -3403,13 +3403,22 @@ struct config_int ConfigureNamesInt[] =
 	{
 		/* see max_connections */
 		{"autovacuum_max_worker_slots", PGC_POSTMASTER, AUTOVACUUM,
-			gettext_noop("Sets the maximum number of simultaneously running autovacuum worker processes."),
-			NULL
+			gettext_noop("Sets the number of backend slots to allocate for autovacuum workers."),
+			gettext_noop("autovacuum_max_workers is silently capped to this value.")
 		},
 		&autovacuum_max_worker_slots,
-		3, 1, MAX_BACKENDS,
+		32, 1, MAX_BACKENDS,
 		check_autovacuum_max_worker_slots, NULL, NULL
 	},
+	{
+		{"autovacuum_max_workers", PGC_SIGHUP, AUTOVACUUM,
+			gettext_noop("Sets the maximum number of simultaneously running autovacuum worker processes."),
+			gettext_noop("This value is silently capped to autovacuum_max_worker_slots.")
+		},
+		&autovacuum_max_workers,
+		3, 1, MAX_BACKENDS,
+		NULL, NULL, NULL
+	},
 
 	{
 		{"max_parallel_maintenance_workers", PGC_USERSET, RESOURCES_ASYNCHRONOUS,
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index c37767cecf..c46d245153 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -658,8 +658,9 @@
 
 #autovacuum = on			# Enable autovacuum subprocess?  'on'
 					# requires track_counts to also be on.
-#autovacuum_max_worker_slots = 3	# max number of autovacuum subprocesses
+autovacuum_max_worker_slots = 32	# autovacuum worker slots to allocate
 					# (change requires restart)
+#autovacuum_max_workers = 3		# max number of autovacuum subprocesses
 #autovacuum_naptime = 1min		# time between autovacuum runs
 #autovacuum_vacuum_threshold = 50	# min number of row updates before
 					# vacuum
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index 754d04485d..598782fd34 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -29,6 +29,7 @@ typedef enum
 /* GUC variables */
 extern PGDLLIMPORT bool autovacuum_start_daemon;
 extern PGDLLIMPORT int autovacuum_max_worker_slots;
+extern PGDLLIMPORT int autovacuum_max_workers;
 extern PGDLLIMPORT int autovacuum_work_mem;
 extern PGDLLIMPORT int autovacuum_naptime;
 extern PGDLLIMPORT int autovacuum_vac_thresh;
diff --git a/src/test/modules/xid_wraparound/t/001_emergency_vacuum.pl b/src/test/modules/xid_wraparound/t/001_emergency_vacuum.pl
index f9cdd50c19..37550b67a4 100644
--- a/src/test/modules/xid_wraparound/t/001_emergency_vacuum.pl
+++ b/src/test/modules/xid_wraparound/t/001_emergency_vacuum.pl
@@ -21,7 +21,7 @@ $node->append_conf(
 autovacuum = off # run autovacuum only when to anti wraparound
 autovacuum_naptime = 1s
 # so it's easier to verify the order of operations
-autovacuum_max_worker_slots = 1
+autovacuum_max_workers = 1
 log_autovacuum_min_duration = 0
 ]);
 $node->start;
diff --git a/src/test/modules/xid_wraparound/t/003_wraparounds.pl b/src/test/modules/xid_wraparound/t/003_wraparounds.pl
index 99f76229d5..88063b4b52 100644
--- a/src/test/modules/xid_wraparound/t/003_wraparounds.pl
+++ b/src/test/modules/xid_wraparound/t/003_wraparounds.pl
@@ -24,7 +24,7 @@ $node->append_conf(
 autovacuum = off # run autovacuum only when to anti wraparound
 autovacuum_naptime = 1s
 # so it's easier to verify the order of operations
-autovacuum_max_worker_slots = 1
+autovacuum_max_workers = 1
 log_autovacuum_min_duration = 0
 ]);
 $node->start;
-- 
2.25.1

