1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-27 22:56:53 +03:00

Lower default value of autovacuum_worker_slots in initdb as needed.

Commit c758119e5b increased the default number of semaphores
required for autovacuum workers from 3 to 16.  Unfortunately, some
systems have very low default settings for SEMMNS, and this change
moved the minimum required for Postgres well beyond that limit (see
commit 38da053463 for more details).

With this commit, initdb will lower the default value for
autovacuum_worker_slots as needed, just like it already does for
parameters such as max_connections and shared_buffers.  We test
for (max_connections / 6) slots, which conveniently has the
following properties:

* For the initial max_connections default of 100, the default of
  autovacuum_worker_slots will be 16, which is its initial default
  value specified in the documentation and in guc_tables.c.

* For the lowest possible max_connections default of 25, the
  default of autovacuum_worker_slots will be 4, which means we only
  need one additional semaphore for autovacuum workers (as compared
  to before commit c758119e5b).  This leaves some wiggle room for
  new auxiliary workers, etc. on systems with low SEMMNS, and it
  ensures that the default number of slots will be greater than or
  equal to the default value of autovacuum_max_workers (3).

Reported-by: Tom Lane
Suggested-by: Andres Freund
Reviewed-by: Tom Lane
Discussion: https://postgr.es/m/1346002.1736198977%40sss.pgh.pa.us
This commit is contained in:
Nathan Bossart 2025-01-07 14:38:55 -06:00
parent 0e5b14410e
commit 6d01541960
2 changed files with 37 additions and 8 deletions

View File

@ -8639,8 +8639,9 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
<listitem> <listitem>
<para> <para>
Specifies the number of backend slots to reserve for autovacuum worker Specifies the number of backend slots to reserve for autovacuum worker
processes. The default is 16. This parameter can only be set at server processes. The default is typically 16 slots, but might be less if
start. your kernel settings will not support it (as determined during initdb).
This parameter can only be set at server start.
</para> </para>
<para> <para>
When changing this value, consider also adjusting When changing this value, consider also adjusting

View File

@ -196,6 +196,7 @@ static char *pgdata_native;
/* defaults */ /* defaults */
static int n_connections = 10; static int n_connections = 10;
static int n_av_slots = 16;
static int n_buffers = 50; static int n_buffers = 50;
static const char *dynamic_shared_memory_type = NULL; static const char *dynamic_shared_memory_type = NULL;
static const char *default_timezone = NULL; static const char *default_timezone = NULL;
@ -273,7 +274,8 @@ static void check_input(char *path);
static void write_version_file(const char *extrapath); static void write_version_file(const char *extrapath);
static void set_null_conf(void); static void set_null_conf(void);
static void test_config_settings(void); static void test_config_settings(void);
static bool test_specific_config_settings(int test_conns, int test_buffs); static bool test_specific_config_settings(int test_conns, int test_av_slots,
int test_buffs);
static void setup_config(void); static void setup_config(void);
static void bootstrap_template1(void); static void bootstrap_template1(void);
static void setup_auth(FILE *cmdfd); static void setup_auth(FILE *cmdfd);
@ -1118,6 +1120,18 @@ test_config_settings(void)
*/ */
#define MIN_BUFS_FOR_CONNS(nconns) ((nconns) * 10) #define MIN_BUFS_FOR_CONNS(nconns) ((nconns) * 10)
/*
* This macro defines the default value of autovacuum_worker_slots we want
* for a given max_connections value. Note that it has been carefully
* crafted to provide specific values for the associated values in
* trial_conns. We want it to return autovacuum_worker_slots's initial
* default value (16) for the maximum value in trial_conns (100), and we
* want it to return close to the minimum value we'd consider (3, which is
* the default of autovacuum_max_workers) for the minimum value in
* trial_conns (25).
*/
#define AV_SLOTS_FOR_CONNS(nconns) ((nconns) / 6)
static const int trial_conns[] = { static const int trial_conns[] = {
100, 50, 40, 30, 25 100, 50, 40, 30, 25
}; };
@ -1145,7 +1159,8 @@ test_config_settings(void)
/* /*
* Probe for max_connections before shared_buffers, since it is subject to * Probe for max_connections before shared_buffers, since it is subject to
* more constraints than shared_buffers. * more constraints than shared_buffers. We also choose the default
* autovacuum_worker_slots here.
*/ */
printf(_("selecting default \"max_connections\" ... ")); printf(_("selecting default \"max_connections\" ... "));
fflush(stdout); fflush(stdout);
@ -1153,9 +1168,10 @@ test_config_settings(void)
for (i = 0; i < connslen; i++) for (i = 0; i < connslen; i++)
{ {
test_conns = trial_conns[i]; test_conns = trial_conns[i];
n_av_slots = AV_SLOTS_FOR_CONNS(test_conns);
test_buffs = MIN_BUFS_FOR_CONNS(test_conns); test_buffs = MIN_BUFS_FOR_CONNS(test_conns);
if (test_specific_config_settings(test_conns, test_buffs)) if (test_specific_config_settings(test_conns, n_av_slots, test_buffs))
{ {
ok_buffers = test_buffs; ok_buffers = test_buffs;
break; break;
@ -1167,6 +1183,13 @@ test_config_settings(void)
printf("%d\n", n_connections); printf("%d\n", n_connections);
/*
* We chose the default for autovacuum_worker_slots during the
* max_connections tests above, but we print a progress message anyway.
*/
printf(_("selecting default \"autovacuum_worker_slots\" ... %d\n"),
n_av_slots);
printf(_("selecting default \"shared_buffers\" ... ")); printf(_("selecting default \"shared_buffers\" ... "));
fflush(stdout); fflush(stdout);
@ -1180,7 +1203,7 @@ test_config_settings(void)
break; break;
} }
if (test_specific_config_settings(n_connections, test_buffs)) if (test_specific_config_settings(n_connections, n_av_slots, test_buffs))
break; break;
} }
n_buffers = test_buffs; n_buffers = test_buffs;
@ -1200,7 +1223,7 @@ test_config_settings(void)
* Test a specific combination of configuration settings. * Test a specific combination of configuration settings.
*/ */
static bool static bool
test_specific_config_settings(int test_conns, int test_buffs) test_specific_config_settings(int test_conns, int test_av_slots, int test_buffs)
{ {
PQExpBufferData cmd; PQExpBufferData cmd;
_stringlist *gnames, _stringlist *gnames,
@ -1213,10 +1236,11 @@ test_specific_config_settings(int test_conns, int test_buffs)
printfPQExpBuffer(&cmd, printfPQExpBuffer(&cmd,
"\"%s\" --check %s %s " "\"%s\" --check %s %s "
"-c max_connections=%d " "-c max_connections=%d "
"-c autovacuum_worker_slots=%d "
"-c shared_buffers=%d " "-c shared_buffers=%d "
"-c dynamic_shared_memory_type=%s", "-c dynamic_shared_memory_type=%s",
backend_exec, boot_options, extra_options, backend_exec, boot_options, extra_options,
test_conns, test_buffs, test_conns, test_av_slots, test_buffs,
dynamic_shared_memory_type); dynamic_shared_memory_type);
/* Add any user-given setting overrides */ /* Add any user-given setting overrides */
@ -1280,6 +1304,10 @@ setup_config(void)
conflines = replace_guc_value(conflines, "max_connections", conflines = replace_guc_value(conflines, "max_connections",
repltok, false); repltok, false);
snprintf(repltok, sizeof(repltok), "%d", n_av_slots);
conflines = replace_guc_value(conflines, "autovacuum_worker_slots",
repltok, false);
if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0) if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0)
snprintf(repltok, sizeof(repltok), "%dMB", snprintf(repltok, sizeof(repltok), "%dMB",
(n_buffers * (BLCKSZ / 1024)) / 1024); (n_buffers * (BLCKSZ / 1024)) / 1024);