Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc758119

Browse files
Allow changing autovacuum_max_workers without restarting.
This commit introduces a new parameter namedautovacuum_worker_slots that controls how many autovacuum workerslots to reserve during server startup. Modifying this newparameter's value does require a server restart, but it shouldtypically be set to the upper bound of what you might realisticallyneed to set autovacuum_max_workers. With that new parameter inplace, autovacuum_max_workers can now be changed with a SIGHUP(e.g., pg_ctl reload).If autovacuum_max_workers is set higher thanautovacuum_worker_slots, a WARNING is emitted, and the server willonly start up to autovacuum_worker_slots workers at a given time.If autovacuum_max_workers is set to a value less than the number ofcurrently-running autovacuum workers, the existing workers willcontinue running, but no new workers will be started until thenumber of running autovacuum workers drops belowautovacuum_max_workers.Reviewed-by: Sami Imseih, Justin Pryzby, Robert Haas, Andres Freund, Yogesh SharmaDiscussion:https://postgr.es/m/20240410212344.GA1824549%40nathanxps13
1 parent5e68f61 commitc758119

File tree

11 files changed

+117
-31
lines changed

11 files changed

+117
-31
lines changed

‎doc/src/sgml/config.sgml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8630,6 +8630,25 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
86308630
</listitem>
86318631
</varlistentry>
86328632

8633+
<varlistentry id="guc-autovacuum-worker-slots" xreflabel="autovacuum_worker_slots">
8634+
<term><varname>autovacuum_worker_slots</varname> (<type>integer</type>)
8635+
<indexterm>
8636+
<primary><varname>autovacuum_worker_slots</varname> configuration parameter</primary>
8637+
</indexterm>
8638+
</term>
8639+
<listitem>
8640+
<para>
8641+
Specifies the number of backend slots to reserve for autovacuum worker
8642+
processes. The default is 16. This parameter can only be set at server
8643+
start.
8644+
</para>
8645+
<para>
8646+
When changing this value, consider also adjusting
8647+
<xref linkend="guc-autovacuum-max-workers"/>.
8648+
</para>
8649+
</listitem>
8650+
</varlistentry>
8651+
86338652
<varlistentry id="guc-autovacuum-max-workers" xreflabel="autovacuum_max_workers">
86348653
<term><varname>autovacuum_max_workers</varname> (<type>integer</type>)
86358654
<indexterm>
@@ -8640,7 +8659,14 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
86408659
<para>
86418660
Specifies the maximum number of autovacuum processes (other than the
86428661
autovacuum launcher) that may be running at any one time. The default
8643-
is three. This parameter can only be set at server start.
8662+
is three. This parameter can only be set in the
8663+
<filename>postgresql.conf</filename> file or on the server command line.
8664+
</para>
8665+
<para>
8666+
Note that a setting for this value which is higher than
8667+
<xref linkend="guc-autovacuum-worker-slots"/> will have no effect,
8668+
since autovacuum workers are taken from the pool of slots established
8669+
by that setting.
86448670
</para>
86458671
</listitem>
86468672
</varlistentry>

‎doc/src/sgml/runtime.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
839839
When using System V semaphores,
840840
<productname>PostgreSQL</productname> uses one semaphore per allowed connection
841841
(<xref linkend="guc-max-connections"/>), allowed autovacuum worker process
842-
(<xref linkend="guc-autovacuum-max-workers"/>), allowed WAL sender process
842+
(<xref linkend="guc-autovacuum-worker-slots"/>), allowed WAL sender process
843843
(<xref linkend="guc-max-wal-senders"/>), allowed background
844844
process (<xref linkend="guc-max-worker-processes"/>), etc., in sets of 19.
845845
The runtime-computed parameter <xref linkend="guc-num-os-semaphores"/>
@@ -892,7 +892,7 @@ $ <userinput>postgres -D $PGDATA -C num_os_semaphores</userinput>
892892
When using POSIX semaphores, the number of semaphores needed is the
893893
same as for System V, that is one semaphore per allowed connection
894894
(<xref linkend="guc-max-connections"/>), allowed autovacuum worker process
895-
(<xref linkend="guc-autovacuum-max-workers"/>), allowed WAL sender process
895+
(<xref linkend="guc-autovacuum-worker-slots"/>), allowed WAL sender process
896896
(<xref linkend="guc-max-wal-senders"/>), allowed background
897897
process (<xref linkend="guc-max-worker-processes"/>), etc.
898898
On the platforms where this option is preferred, there is no specific

‎src/backend/access/transam/xlog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5403,7 +5403,7 @@ CheckRequiredParameterValues(void)
54035403
*/
54045404
if (ArchiveRecoveryRequested&&EnableHotStandby)
54055405
{
5406-
/* We ignoreautovacuum_max_workers when we make this test. */
5406+
/* We ignoreautovacuum_worker_slots when we make this test. */
54075407
RecoveryRequiresIntParameter("max_connections",
54085408
MaxConnections,
54095409
ControlFile->MaxConnections);

‎src/backend/postmaster/autovacuum.c

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
* GUC parameters
116116
*/
117117
boolautovacuum_start_daemon= false;
118+
intautovacuum_worker_slots;
118119
intautovacuum_max_workers;
119120
intautovacuum_work_mem=-1;
120121
intautovacuum_naptime;
@@ -210,7 +211,7 @@ typedef struct autovac_table
210211
/*-------------
211212
* This struct holds information about a single worker's whereabouts. We keep
212213
* an array of these in shared memory, sized according to
213-
*autovacuum_max_workers.
214+
*autovacuum_worker_slots.
214215
*
215216
* wi_linksentry into free list or running list
216217
* wi_dboidOID of the database this worker is supposed to work on
@@ -291,7 +292,7 @@ typedef struct
291292
{
292293
sig_atomic_tav_signal[AutoVacNumSignals];
293294
pid_tav_launcherpid;
294-
dlist_headav_freeWorkers;
295+
dclist_headav_freeWorkers;
295296
dlist_headav_runningWorkers;
296297
WorkerInfoav_startingWorker;
297298
AutoVacuumWorkItemav_workItems[NUM_WORKITEMS];
@@ -349,6 +350,8 @@ static void autovac_report_activity(autovac_table *tab);
349350
staticvoidautovac_report_workitem(AutoVacuumWorkItem*workitem,
350351
constchar*nspname,constchar*relname);
351352
staticvoidavl_sigusr2_handler(SIGNAL_ARGS);
353+
staticboolav_worker_available(void);
354+
staticvoidcheck_av_worker_gucs(void);
352355

353356

354357

@@ -577,8 +580,7 @@ AutoVacLauncherMain(char *startup_data, size_t startup_data_len)
577580
* wakening conditions.
578581
*/
579582

580-
launcher_determine_sleep(!dlist_is_empty(&AutoVacuumShmem->av_freeWorkers),
581-
false,&nap);
583+
launcher_determine_sleep(av_worker_available(), false,&nap);
582584

583585
/*
584586
* Wait until naptime expires or we get some type of signal (all the
@@ -638,7 +640,7 @@ AutoVacLauncherMain(char *startup_data, size_t startup_data_len)
638640
current_time=GetCurrentTimestamp();
639641
LWLockAcquire(AutovacuumLock,LW_SHARED);
640642

641-
can_launch=!dlist_is_empty(&AutoVacuumShmem->av_freeWorkers);
643+
can_launch=av_worker_available();
642644

643645
if (AutoVacuumShmem->av_startingWorker!=NULL)
644646
{
@@ -681,8 +683,8 @@ AutoVacLauncherMain(char *startup_data, size_t startup_data_len)
681683
worker->wi_sharedrel= false;
682684
worker->wi_proc=NULL;
683685
worker->wi_launchtime=0;
684-
dlist_push_head(&AutoVacuumShmem->av_freeWorkers,
685-
&worker->wi_links);
686+
dclist_push_head(&AutoVacuumShmem->av_freeWorkers,
687+
&worker->wi_links);
686688
AutoVacuumShmem->av_startingWorker=NULL;
687689
ereport(WARNING,
688690
errmsg("autovacuum worker took too long to start; canceled"));
@@ -747,13 +749,23 @@ HandleAutoVacLauncherInterrupts(void)
747749

748750
if (ConfigReloadPending)
749751
{
752+
intautovacuum_max_workers_prev=autovacuum_max_workers;
753+
750754
ConfigReloadPending= false;
751755
ProcessConfigFile(PGC_SIGHUP);
752756

753757
/* shutdown requested in config file? */
754758
if (!AutoVacuumingActive())
755759
AutoVacLauncherShutdown();
756760

761+
/*
762+
* If autovacuum_max_workers changed, emit a WARNING if
763+
* autovacuum_worker_slots < autovacuum_max_workers. If it didn't
764+
* change, skip this to avoid too many repeated log messages.
765+
*/
766+
if (autovacuum_max_workers_prev!=autovacuum_max_workers)
767+
check_av_worker_gucs();
768+
757769
/* rebuild the list in case the naptime changed */
758770
rebuild_database_list(InvalidOid);
759771
}
@@ -1089,7 +1101,7 @@ do_start_worker(void)
10891101

10901102
/* return quickly when there are no free workers */
10911103
LWLockAcquire(AutovacuumLock,LW_SHARED);
1092-
if (dlist_is_empty(&AutoVacuumShmem->av_freeWorkers))
1104+
if (!av_worker_available())
10931105
{
10941106
LWLockRelease(AutovacuumLock);
10951107
returnInvalidOid;
@@ -1242,7 +1254,7 @@ do_start_worker(void)
12421254
* Get a worker entry from the freelist. We checked above, so there
12431255
* really should be a free slot.
12441256
*/
1245-
wptr=dlist_pop_head_node(&AutoVacuumShmem->av_freeWorkers);
1257+
wptr=dclist_pop_head_node(&AutoVacuumShmem->av_freeWorkers);
12461258

12471259
worker=dlist_container(WorkerInfoData,wi_links,wptr);
12481260
worker->wi_dboid=avdb->adw_datid;
@@ -1615,8 +1627,8 @@ FreeWorkerInfo(int code, Datum arg)
16151627
MyWorkerInfo->wi_proc=NULL;
16161628
MyWorkerInfo->wi_launchtime=0;
16171629
pg_atomic_clear_flag(&MyWorkerInfo->wi_dobalance);
1618-
dlist_push_head(&AutoVacuumShmem->av_freeWorkers,
1619-
&MyWorkerInfo->wi_links);
1630+
dclist_push_head(&AutoVacuumShmem->av_freeWorkers,
1631+
&MyWorkerInfo->wi_links);
16201632
/* not mine anymore */
16211633
MyWorkerInfo=NULL;
16221634

@@ -3248,10 +3260,14 @@ AutoVacuumRequestWork(AutoVacuumWorkItemType type, Oid relationId,
32483260
void
32493261
autovac_init(void)
32503262
{
3251-
if (autovacuum_start_daemon&& !pgstat_track_counts)
3263+
if (!autovacuum_start_daemon)
3264+
return;
3265+
elseif (!pgstat_track_counts)
32523266
ereport(WARNING,
32533267
(errmsg("autovacuum not started because of misconfiguration"),
32543268
errhint("Enable the \"track_counts\" option.")));
3269+
else
3270+
check_av_worker_gucs();
32553271
}
32563272

32573273
/*
@@ -3268,7 +3284,7 @@ AutoVacuumShmemSize(void)
32683284
*/
32693285
size=sizeof(AutoVacuumShmemStruct);
32703286
size=MAXALIGN(size);
3271-
size=add_size(size,mul_size(autovacuum_max_workers,
3287+
size=add_size(size,mul_size(autovacuum_worker_slots,
32723288
sizeof(WorkerInfoData)));
32733289
returnsize;
32743290
}
@@ -3295,7 +3311,7 @@ AutoVacuumShmemInit(void)
32953311
Assert(!found);
32963312

32973313
AutoVacuumShmem->av_launcherpid=0;
3298-
dlist_init(&AutoVacuumShmem->av_freeWorkers);
3314+
dclist_init(&AutoVacuumShmem->av_freeWorkers);
32993315
dlist_init(&AutoVacuumShmem->av_runningWorkers);
33003316
AutoVacuumShmem->av_startingWorker=NULL;
33013317
memset(AutoVacuumShmem->av_workItems,0,
@@ -3305,10 +3321,10 @@ AutoVacuumShmemInit(void)
33053321
MAXALIGN(sizeof(AutoVacuumShmemStruct)));
33063322

33073323
/* initialize the WorkerInfo free list */
3308-
for (i=0;i<autovacuum_max_workers;i++)
3324+
for (i=0;i<autovacuum_worker_slots;i++)
33093325
{
3310-
dlist_push_head(&AutoVacuumShmem->av_freeWorkers,
3311-
&worker[i].wi_links);
3326+
dclist_push_head(&AutoVacuumShmem->av_freeWorkers,
3327+
&worker[i].wi_links);
33123328
pg_atomic_init_flag(&worker[i].wi_dobalance);
33133329
}
33143330

@@ -3344,3 +3360,35 @@ check_autovacuum_work_mem(int *newval, void **extra, GucSource source)
33443360

33453361
return true;
33463362
}
3363+
3364+
/*
3365+
* Returns whether there is a free autovacuum worker slot available.
3366+
*/
3367+
staticbool
3368+
av_worker_available(void)
3369+
{
3370+
intfree_slots;
3371+
intreserved_slots;
3372+
3373+
free_slots=dclist_count(&AutoVacuumShmem->av_freeWorkers);
3374+
3375+
reserved_slots=autovacuum_worker_slots-autovacuum_max_workers;
3376+
reserved_slots=Max(0,reserved_slots);
3377+
3378+
returnfree_slots>reserved_slots;
3379+
}
3380+
3381+
/*
3382+
* Emits a WARNING if autovacuum_worker_slots < autovacuum_max_workers.
3383+
*/
3384+
staticvoid
3385+
check_av_worker_gucs(void)
3386+
{
3387+
if (autovacuum_worker_slots<autovacuum_max_workers)
3388+
ereport(WARNING,
3389+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3390+
errmsg("\"autovacuum_max_workers\" (%d) should be less than or equal to \"autovacuum_worker_slots\" (%d)",
3391+
autovacuum_max_workers,autovacuum_worker_slots),
3392+
errdetail("The server will only start up to \"autovacuum_worker_slots\" (%d) autovacuum workers at a given time.",
3393+
autovacuum_worker_slots)));
3394+
}

‎src/backend/postmaster/pmchild.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* child process is allocated a PMChild struct from a fixed pool of structs.
99
* The size of the pool is determined by various settings that configure how
1010
* many worker processes and backend connections are allowed, i.e.
11-
*autovacuum_max_workers, max_worker_processes, max_wal_senders, and
11+
*autovacuum_worker_slots, max_worker_processes, max_wal_senders, and
1212
* max_connections.
1313
*
1414
* Dead-end backends are handled slightly differently. There is no limit
@@ -99,7 +99,7 @@ InitPostmasterChildSlots(void)
9999
*/
100100
pmchild_pools[B_BACKEND].size=2* (MaxConnections+max_wal_senders);
101101

102-
pmchild_pools[B_AUTOVAC_WORKER].size=autovacuum_max_workers;
102+
pmchild_pools[B_AUTOVAC_WORKER].size=autovacuum_worker_slots;
103103
pmchild_pools[B_BG_WORKER].size=max_worker_processes;
104104

105105
/*

‎src/backend/storage/lmgr/proc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ ProcGlobalSemas(void)
150150
* So, now we grab enough semaphores to support the desired max number
151151
* of backends immediately at initialization --- if the sysadmin has set
152152
* MaxConnections, max_worker_processes, max_wal_senders, or
153-
*autovacuum_max_workers higher than his kernel will support, he'll
153+
*autovacuum_worker_slots higher than his kernel will support, he'll
154154
* find out sooner rather than later.
155155
*
156156
* Another reason for creating semaphores here is that the semaphore
@@ -284,13 +284,13 @@ InitProcGlobal(void)
284284
dlist_push_tail(&ProcGlobal->freeProcs,&proc->links);
285285
proc->procgloballist=&ProcGlobal->freeProcs;
286286
}
287-
elseif (i<MaxConnections+autovacuum_max_workers+NUM_SPECIAL_WORKER_PROCS)
287+
elseif (i<MaxConnections+autovacuum_worker_slots+NUM_SPECIAL_WORKER_PROCS)
288288
{
289289
/* PGPROC for AV or special worker, add to autovacFreeProcs list */
290290
dlist_push_tail(&ProcGlobal->autovacFreeProcs,&proc->links);
291291
proc->procgloballist=&ProcGlobal->autovacFreeProcs;
292292
}
293-
elseif (i<MaxConnections+autovacuum_max_workers+NUM_SPECIAL_WORKER_PROCS+max_worker_processes)
293+
elseif (i<MaxConnections+autovacuum_worker_slots+NUM_SPECIAL_WORKER_PROCS+max_worker_processes)
294294
{
295295
/* PGPROC for bgworker, add to bgworkerFreeProcs list */
296296
dlist_push_tail(&ProcGlobal->bgworkerFreeProcs,&proc->links);

‎src/backend/utils/init/postinit.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -547,15 +547,15 @@ InitializeMaxBackends(void)
547547
Assert(MaxBackends==0);
548548

549549
/* Note that this does not include "auxiliary" processes */
550-
MaxBackends=MaxConnections+autovacuum_max_workers+
550+
MaxBackends=MaxConnections+autovacuum_worker_slots+
551551
max_worker_processes+max_wal_senders+NUM_SPECIAL_WORKER_PROCS;
552552

553553
if (MaxBackends>MAX_BACKENDS)
554554
ereport(ERROR,
555555
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
556556
errmsg("too many server processes configured"),
557-
errdetail("\"max_connections\" (%d) plus \"autovacuum_max_workers\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d.",
558-
MaxConnections,autovacuum_max_workers,
557+
errdetail("\"max_connections\" (%d) plus \"autovacuum_worker_slots\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d.",
558+
MaxConnections,autovacuum_worker_slots,
559559
max_worker_processes,max_wal_senders,
560560
MAX_BACKENDS- (NUM_SPECIAL_WORKER_PROCS-1))));
561561
}

‎src/backend/utils/misc/guc_tables.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3467,7 +3467,16 @@ struct config_int ConfigureNamesInt[] =
34673467
},
34683468
{
34693469
/* see max_connections */
3470-
{"autovacuum_max_workers",PGC_POSTMASTER,AUTOVACUUM,
3470+
{"autovacuum_worker_slots",PGC_POSTMASTER,AUTOVACUUM,
3471+
gettext_noop("Sets the number of backend slots to allocate for autovacuum workers."),
3472+
NULL
3473+
},
3474+
&autovacuum_worker_slots,
3475+
16,1,MAX_BACKENDS,
3476+
NULL,NULL,NULL
3477+
},
3478+
{
3479+
{"autovacuum_max_workers",PGC_SIGHUP,AUTOVACUUM,
34713480
gettext_noop("Sets the maximum number of simultaneously running autovacuum worker processes."),
34723481
NULL
34733482
},

‎src/backend/utils/misc/postgresql.conf.sample

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,8 +661,9 @@
661661

662662
#autovacuum = on# Enable autovacuum subprocess? 'on'
663663
# requires track_counts to also be on.
664-
#autovacuum_max_workers =3# max number of autovacuum subprocesses
664+
autovacuum_worker_slots =16# autovacuum worker slots to allocate
665665
# (change requires restart)
666+
#autovacuum_max_workers = 3# max number of autovacuum subprocesses
666667
#autovacuum_naptime = 1min# time between autovacuum runs
667668
#autovacuum_vacuum_threshold = 50# min number of row updates before
668669
# vacuum

‎src/include/postmaster/autovacuum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ typedef enum
2828

2929
/* GUC variables */
3030
externPGDLLIMPORTboolautovacuum_start_daemon;
31+
externPGDLLIMPORTintautovacuum_worker_slots;
3132
externPGDLLIMPORTintautovacuum_max_workers;
3233
externPGDLLIMPORTintautovacuum_work_mem;
3334
externPGDLLIMPORTintautovacuum_naptime;

‎src/test/perl/PostgreSQL/Test/Cluster.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@ sub init
707707
}
708708
print$conf"max_wal_senders = 10\n";
709709
print$conf"max_replication_slots = 10\n";
710+
print$conf"autovacuum_worker_slots = 3\n";
710711
print$conf"wal_log_hints = on\n";
711712
print$conf"hot_standby = on\n";
712713
# conservative settings to ensure we can run multiple postmasters:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp