From 795776af97d5f3ab05e48c7b78367bf6290e7ad4 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Mon, 27 Mar 2023 13:33:19 -0400 Subject: [PATCH v12 3/4] VACUUM reloads config file more often Previously, VACUUM would not reload the configuration file, so changes to cost-based delay parameters could only take effect on the next invocation of VACUUM. Now, check if a reload is pending roughly once per block, when checking if we need to delay. Note that autovacuum is unaffected by this change. Autovacuum workers overwrite the value of VacuumCostLimit and VacuumCostDelay with their own WorkerInfo->wi_cost_limit and wi_cost_delay instead of using potentially refreshed values of autovacuum_vacuum_cost_limit and autovacuum_vacuum_cost_delay. Locking considerations and needed updates to the worker balancing logic make enabling this feature for autovacuum worthy of an independent commit. Reviewed-by: Masahiko Sawada Reviewed-by: Kyotaro Horiguchi Reviewed-by: Daniel Gustafsson Discussion: https://www.postgresql.org/message-id/flat/CAAKRu_ZngzqnEODc7LmS1NH04Kt6Y9huSjz5pp7%2BDXhrjDA0gw%40mail.gmail.com --- src/backend/commands/vacuum.c | 46 +++++++++++++++++++++------ src/backend/commands/vacuumparallel.c | 3 +- src/backend/postmaster/autovacuum.c | 18 +++++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 2c3afd4ff6..a288c402a9 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -48,6 +48,7 @@ #include "pgstat.h" #include "postmaster/autovacuum.h" #include "postmaster/bgworker_internals.h" +#include "postmaster/interrupt.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "storage/pmsignal.h" @@ -78,6 +79,7 @@ int vacuum_cost_limit; /* A few variables that don't seem worth passing around as parameters */ static MemoryContext vac_context = NULL; static BufferAccessStrategy vac_strategy; +static bool analyze_in_outer_xact = false; /* * Variables for cost-based vacuum delay. The defaults differ between @@ -325,8 +327,7 @@ vacuum(List *relations, VacuumParams *params, static bool in_vacuum = false; const char *stmttype; - volatile bool in_outer_xact, - use_own_xacts; + volatile bool use_own_xacts; Assert(params != NULL); @@ -343,10 +344,10 @@ vacuum(List *relations, VacuumParams *params, if (params->options & VACOPT_VACUUM) { PreventInTransactionBlock(isTopLevel, stmttype); - in_outer_xact = false; + analyze_in_outer_xact = false; } else - in_outer_xact = IsInTransactionBlock(isTopLevel); + analyze_in_outer_xact = IsInTransactionBlock(isTopLevel); /* * Due to static variables vac_context, anl_context and vac_strategy, @@ -468,7 +469,7 @@ vacuum(List *relations, VacuumParams *params, Assert(params->options & VACOPT_ANALYZE); if (IsAutoVacuumWorkerProcess()) use_own_xacts = true; - else if (in_outer_xact) + else if (analyze_in_outer_xact) use_own_xacts = false; else if (list_length(relations) > 1) use_own_xacts = true; @@ -486,7 +487,7 @@ vacuum(List *relations, VacuumParams *params, */ if (use_own_xacts) { - Assert(!in_outer_xact); + Assert(!analyze_in_outer_xact); /* ActiveSnapshot is not set by autovacuum */ if (ActiveSnapshotSet()) @@ -501,9 +502,9 @@ vacuum(List *relations, VacuumParams *params, { ListCell *cur; - VacuumUpdateCosts(); in_vacuum = true; - VacuumCostActive = (VacuumCostDelay > 0); + VacuumFailsafeActive = false; + VacuumUpdateCosts(); VacuumCostBalance = 0; VacuumPageHit = 0; VacuumPageMiss = 0; @@ -539,7 +540,7 @@ vacuum(List *relations, VacuumParams *params, } analyze_rel(vrel->oid, vrel->relation, params, - vrel->va_cols, in_outer_xact, vac_strategy); + vrel->va_cols, analyze_in_outer_xact, vac_strategy); if (use_own_xacts) { @@ -562,6 +563,9 @@ vacuum(List *relations, VacuumParams *params, { in_vacuum = false; VacuumCostActive = false; + VacuumFailsafeActive = false; + VacuumCostBalance = 0; + analyze_in_outer_xact = false; } PG_END_TRY(); @@ -2227,7 +2231,29 @@ vacuum_delay_point(void) /* Always check for interrupts */ CHECK_FOR_INTERRUPTS(); - if (!VacuumCostActive || InterruptPending) + if (InterruptPending || + (!VacuumCostActive && !ConfigReloadPending)) + return; + + /* + * Reload the configuration file if requested. This allows changes to + * vacuum_cost_limit and vacuum_cost_delay to take effect while a table is + * being vacuumed or analyzed. Analyze should not reload configuration + * file if it is in an outer transaction, as we currently only allow + * configuration reload when in top-level statements. + */ + if (ConfigReloadPending && !analyze_in_outer_xact) + { + ConfigReloadPending = false; + ProcessConfigFile(PGC_SIGHUP); + VacuumUpdateCosts(); + } + + /* + * If we disabled cost-based delays after reloading the config file, + * return. + */ + if (!VacuumCostActive) return; /* diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index 4c3c93b2fd..36963090e8 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -991,9 +991,8 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) /* Set cost-based vacuum delay */ VacuumFailsafeActive = false; - VacuumUpdateCosts(); - VacuumCostActive = (VacuumCostDelay > 0); VacuumCostBalance = 0; + VacuumUpdateCosts(); VacuumPageHit = 0; VacuumPageMiss = 0; VacuumPageDirty = 0; diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index ac54ed4546..e7833cd49e 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -1797,6 +1797,24 @@ VacuumUpdateCosts(void) VacuumCostLimit = vacuum_cost_limit; VacuumCostDelay = vacuum_cost_delay; } + + /* + * If configuration changes are allowed to impact VacuumCostActive, + * make sure it is updated. + */ + if (VacuumFailsafeActive) + { + Assert(!VacuumCostActive); + return; + } + + if (VacuumCostDelay > 0) + VacuumCostActive = true; + else + { + VacuumCostActive = false; + VacuumCostBalance = 0; + } } -- 2.37.2