v19-0002-Separate-vacuum-cost-variables-from-GUCs.patch
text/x-patch
Filename: v19-0002-Separate-vacuum-cost-variables-from-GUCs.patch
Type: text/x-patch
Part: 2
Patch
Format: format-patch
Series: patch v19-0002
Subject: Separate vacuum cost variables from GUCs
| File | + | − |
|---|---|---|
| src/backend/commands/vacuum.c | 19 | 10 |
| src/backend/commands/vacuumparallel.c | 2 | 1 |
| src/backend/postmaster/autovacuum.c | 14 | 20 |
| src/include/commands/vacuum.h | 5 | 0 |
| src/include/postmaster/autovacuum.h | 0 | 3 |
From 92fc87969a496c1a1f5fd612d3c7c32251dec6e1 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Thu, 6 Apr 2023 16:02:12 -0400
Subject: [PATCH v19 2/3] Separate vacuum cost variables from GUCs
Vacuum code run both by autovacuum workers and a backend doing
VACUUM/ANALYZE previously inspected VacuumCostLimit and VacuumCostDelay,
which are the global variables backing the GUCs vacuum_cost_limit and
vacuum_cost_delay.
Autovacuum workers needed to override these variables with their own
values, derived from autovacuum_vacuum_cost_limit and
autovacuum_vacuum_cost_delay and worker cost limit balancing logic. This
led to confusing code which, in some cases, both derived and set a new
value of VacuumCostLimit from VacuumCostLimit.
In preparation for refreshing these GUC values more often, introduce
new, independent global variables and add a function to update them
using the GUCs and existing logic.
Per suggestion by Kyotaro Horiguchi
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CAAKRu_ZngzqnEODc7LmS1NH04Kt6Y9huSjz5pp7%2BDXhrjDA0gw%40mail.gmail.com
---
src/backend/commands/vacuum.c | 29 +++++++++++++++--------
src/backend/commands/vacuumparallel.c | 3 ++-
src/backend/postmaster/autovacuum.c | 34 +++++++++++----------------
src/include/commands/vacuum.h | 5 ++++
src/include/postmaster/autovacuum.h | 3 ---
5 files changed, 40 insertions(+), 34 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 7fc5c19e37..f2be74cdb5 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -72,6 +72,15 @@ int vacuum_multixact_freeze_table_age;
int vacuum_failsafe_age;
int vacuum_multixact_failsafe_age;
+/*
+ * Variables for cost-based vacuum delay. The defaults differ between
+ * autovacuum and vacuum. They should be set with the appropriate GUC value in
+ * vacuum code. They are initialized here to the defaults for client backends
+ * executing VACUUM or ANALYZE.
+ */
+double vacuum_cost_delay = 0;
+int vacuum_cost_limit = 200;
+
/*
* VacuumFailsafeActive is a defined as a global so that we can determine
* whether or not to re-enable cost-based vacuum delay when vacuuming a table.
@@ -514,8 +523,9 @@ vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy,
{
ListCell *cur;
+ VacuumUpdateCosts();
in_vacuum = true;
- VacuumCostActive = (VacuumCostDelay > 0);
+ VacuumCostActive = (vacuum_cost_delay > 0);
VacuumCostBalance = 0;
VacuumPageHit = 0;
VacuumPageMiss = 0;
@@ -2244,14 +2254,14 @@ vacuum_delay_point(void)
*/
if (VacuumSharedCostBalance != NULL)
msec = compute_parallel_delay();
- else if (VacuumCostBalance >= VacuumCostLimit)
- msec = VacuumCostDelay * VacuumCostBalance / VacuumCostLimit;
+ else if (VacuumCostBalance >= vacuum_cost_limit)
+ msec = vacuum_cost_delay * VacuumCostBalance / vacuum_cost_limit;
/* Nap if appropriate */
if (msec > 0)
{
- if (msec > VacuumCostDelay * 4)
- msec = VacuumCostDelay * 4;
+ if (msec > vacuum_cost_delay * 4)
+ msec = vacuum_cost_delay * 4;
pgstat_report_wait_start(WAIT_EVENT_VACUUM_DELAY);
pg_usleep(msec * 1000);
@@ -2268,8 +2278,7 @@ vacuum_delay_point(void)
VacuumCostBalance = 0;
- /* update balance values for workers */
- AutoVacuumUpdateDelay();
+ VacuumUpdateCosts();
/* Might have gotten an interrupt while sleeping */
CHECK_FOR_INTERRUPTS();
@@ -2319,11 +2328,11 @@ compute_parallel_delay(void)
/* Compute the total local balance for the current worker */
VacuumCostBalanceLocal += VacuumCostBalance;
- if ((shared_balance >= VacuumCostLimit) &&
- (VacuumCostBalanceLocal > 0.5 * ((double) VacuumCostLimit / nworkers)))
+ if ((shared_balance >= vacuum_cost_limit) &&
+ (VacuumCostBalanceLocal > 0.5 * ((double) vacuum_cost_limit / nworkers)))
{
/* Compute sleep time based on the local cost balance */
- msec = VacuumCostDelay * VacuumCostBalanceLocal / VacuumCostLimit;
+ msec = vacuum_cost_delay * VacuumCostBalanceLocal / vacuum_cost_limit;
pg_atomic_sub_fetch_u32(VacuumSharedCostBalance, VacuumCostBalanceLocal);
VacuumCostBalanceLocal = 0;
}
diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c
index 563117a8f6..cc0aff7904 100644
--- a/src/backend/commands/vacuumparallel.c
+++ b/src/backend/commands/vacuumparallel.c
@@ -995,7 +995,8 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
false);
/* Set cost-based vacuum delay */
- VacuumCostActive = (VacuumCostDelay > 0);
+ VacuumCostActive = (vacuum_cost_delay > 0);
+ VacuumUpdateCosts();
VacuumCostBalance = 0;
VacuumPageHit = 0;
VacuumPageMiss = 0;
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index c1e911b1b3..3644b86443 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -1773,16 +1773,24 @@ FreeWorkerInfo(int code, Datum arg)
}
/*
- * Update the cost-based delay parameters, so that multiple workers consume
- * each a fraction of the total available I/O.
+ * Update vacuum cost-based delay-related parameters for autovacuum workers and
+ * backends executing VACUUM or ANALYZE using the value of relevant gucs and
+ * global state. This must be called during setup for vacuum and after every
+ * config reload to ensure up-to-date values.
*/
void
-AutoVacuumUpdateDelay(void)
+VacuumUpdateCosts(void)
{
if (MyWorkerInfo)
{
- VacuumCostDelay = MyWorkerInfo->wi_cost_delay;
- VacuumCostLimit = MyWorkerInfo->wi_cost_limit;
+ vacuum_cost_delay = MyWorkerInfo->wi_cost_delay;
+ vacuum_cost_limit = MyWorkerInfo->wi_cost_limit;
+ }
+ else
+ {
+ /* Must be explicit VACUUM or ANALYZE */
+ vacuum_cost_delay = VacuumCostDelay;
+ vacuum_cost_limit = VacuumCostLimit;
}
}
@@ -2311,8 +2319,6 @@ do_autovacuum(void)
autovac_table *tab;
bool isshared;
bool skipit;
- double stdVacuumCostDelay;
- int stdVacuumCostLimit;
dlist_iter iter;
CHECK_FOR_INTERRUPTS();
@@ -2415,14 +2421,6 @@ do_autovacuum(void)
continue;
}
- /*
- * Remember the prevailing values of the vacuum cost GUCs. We have to
- * restore these at the bottom of the loop, else we'll compute wrong
- * values in the next iteration of autovac_balance_cost().
- */
- stdVacuumCostDelay = VacuumCostDelay;
- stdVacuumCostLimit = VacuumCostLimit;
-
/* Must hold AutovacuumLock while mucking with cost balance info */
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
@@ -2436,7 +2434,7 @@ do_autovacuum(void)
autovac_balance_cost();
/* set the active cost parameters from the result of that */
- AutoVacuumUpdateDelay();
+ VacuumUpdateCosts();
/* done */
LWLockRelease(AutovacuumLock);
@@ -2533,10 +2531,6 @@ deleted:
MyWorkerInfo->wi_tableoid = InvalidOid;
MyWorkerInfo->wi_sharedrel = false;
LWLockRelease(AutovacuumScheduleLock);
-
- /* restore vacuum cost GUCs for the next iteration */
- VacuumCostDelay = stdVacuumCostDelay;
- VacuumCostLimit = stdVacuumCostLimit;
}
/*
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 1223d15e0d..50caf1315d 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -307,6 +307,8 @@ extern PGDLLIMPORT pg_atomic_uint32 *VacuumActiveNWorkers;
extern PGDLLIMPORT int VacuumCostBalanceLocal;
extern PGDLLIMPORT bool VacuumFailsafeActive;
+extern PGDLLIMPORT double vacuum_cost_delay;
+extern PGDLLIMPORT int vacuum_cost_limit;
/* in commands/vacuum.c */
extern void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel);
@@ -347,6 +349,9 @@ extern IndexBulkDeleteResult *vac_cleanup_one_index(IndexVacuumInfo *ivinfo,
IndexBulkDeleteResult *istat);
extern Size vac_max_items_to_alloc_size(int max_items);
+/* In postmaster/autovacuum.c */
+extern void VacuumUpdateCosts(void);
+
/* in commands/vacuumparallel.c */
extern ParallelVacuumState *parallel_vacuum_init(Relation rel, Relation *indrels,
int nindexes, int nrequested_workers,
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index c140371b51..65afd1ea1e 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -63,9 +63,6 @@ extern int StartAutoVacWorker(void);
/* called from postmaster when a worker could not be forked */
extern void AutoVacWorkerFailed(void);
-/* autovacuum cost-delay balancer */
-extern void AutoVacuumUpdateDelay(void);
-
#ifdef EXEC_BACKEND
extern void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn();
extern void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn();
--
2.37.2