From df724144b6fbdc804fb91033bd88df0f82ba6f30 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Mon, 27 Mar 2023 13:33:19 -0400 Subject: [PATCH v10 2/3] 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. Check if a reload is pending roughly once per block now, 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. Writing to their wi_cost_delay more often makes reading wi_cost_delay without a lock to update VacuumCostDelay an even worse idea. Reviewed-by: Masahiko Sawada Reviewed-by: Daniel Gustafsson Discussion: https://www.postgresql.org/message-id/flat/CAAKRu_buP5wzsho3qNw5o9_R0pF69FRM5hgCmr-mvXmGXwdA7A%40mail.gmail.com#5e6771d4cdca4db6efc2acec2dce0bc7 --- src/backend/commands/vacuum.c | 61 ++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index eb126f2247..7e3a8e404e 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" @@ -76,6 +77,7 @@ int vacuum_multixact_failsafe_age; /* 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; /* @@ -314,8 +316,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); @@ -332,10 +333,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, @@ -457,7 +458,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; @@ -475,7 +476,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()) @@ -544,7 +545,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) { @@ -568,6 +569,7 @@ vacuum(List *relations, VacuumParams *params, in_vacuum = false; VacuumCostInactive = VACUUM_COST_INACTIVE_AND_UNLOCKED; VacuumCostBalance = 0; + analyze_in_outer_xact = false; } PG_END_TRY(); @@ -2233,7 +2235,50 @@ vacuum_delay_point(void) /* Always check for interrupts */ CHECK_FOR_INTERRUPTS(); - if (VacuumCostInactive || InterruptPending) + if (InterruptPending || + (VacuumCostInactive && !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); + + /* + * Autovacuum workers must restore the correct values of + * VacuumCostLimit and VacuumCostDelay in case they were overwritten + * by reload. + */ + AutoVacuumUpdateDelay(); + + /* + * If configuration changes are allowed to impact VacuumCostInactive, + * make sure it is updated. + */ + if (VacuumCostInactive == VACUUM_COST_INACTIVE_AND_LOCKED) + return; + + if (VacuumCostDelay > 0) + VacuumCostInactive = VACUUM_COST_ACTIVE; + else + { + VacuumCostInactive = VACUUM_COST_INACTIVE_AND_UNLOCKED; + VacuumCostBalance = 0; + } + } + + /* + * If we disabled cost-based delays after reloading the config file, + * return. + */ + if (VacuumCostInactive) return; /* -- 2.37.2