Skip to content

Commit a85c60a

Browse files
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 Author: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com> Reviewed-by: Daniel Gustafsson <daniel@yesql.se> Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/CAAKRu_ZngzqnEODc7LmS1NH04Kt6Y9huSjz5pp7%2BDXhrjDA0gw%40mail.gmail.com
1 parent 71a8251 commit a85c60a

File tree

5 files changed

+40
-34
lines changed

5 files changed

+40
-34
lines changed

src/backend/commands/vacuum.c

+19-10
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ int vacuum_multixact_freeze_table_age;
7272
int vacuum_failsafe_age;
7373
int vacuum_multixact_failsafe_age;
7474

75+
/*
76+
* Variables for cost-based vacuum delay. The defaults differ between
77+
* autovacuum and vacuum. They should be set with the appropriate GUC value in
78+
* vacuum code. They are initialized here to the defaults for client backends
79+
* executing VACUUM or ANALYZE.
80+
*/
81+
double vacuum_cost_delay = 0;
82+
int vacuum_cost_limit = 200;
83+
7584
/*
7685
* VacuumFailsafeActive is a defined as a global so that we can determine
7786
* 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,
514523
{
515524
ListCell *cur;
516525

526+
VacuumUpdateCosts();
517527
in_vacuum = true;
518-
VacuumCostActive = (VacuumCostDelay > 0);
528+
VacuumCostActive = (vacuum_cost_delay > 0);
519529
VacuumCostBalance = 0;
520530
VacuumPageHit = 0;
521531
VacuumPageMiss = 0;
@@ -2244,14 +2254,14 @@ vacuum_delay_point(void)
22442254
*/
22452255
if (VacuumSharedCostBalance != NULL)
22462256
msec = compute_parallel_delay();
2247-
else if (VacuumCostBalance >= VacuumCostLimit)
2248-
msec = VacuumCostDelay * VacuumCostBalance / VacuumCostLimit;
2257+
else if (VacuumCostBalance >= vacuum_cost_limit)
2258+
msec = vacuum_cost_delay * VacuumCostBalance / vacuum_cost_limit;
22492259

22502260
/* Nap if appropriate */
22512261
if (msec > 0)
22522262
{
2253-
if (msec > VacuumCostDelay * 4)
2254-
msec = VacuumCostDelay * 4;
2263+
if (msec > vacuum_cost_delay * 4)
2264+
msec = vacuum_cost_delay * 4;
22552265

22562266
pgstat_report_wait_start(WAIT_EVENT_VACUUM_DELAY);
22572267
pg_usleep(msec * 1000);
@@ -2268,8 +2278,7 @@ vacuum_delay_point(void)
22682278

22692279
VacuumCostBalance = 0;
22702280

2271-
/* update balance values for workers */
2272-
AutoVacuumUpdateDelay();
2281+
VacuumUpdateCosts();
22732282

22742283
/* Might have gotten an interrupt while sleeping */
22752284
CHECK_FOR_INTERRUPTS();
@@ -2319,11 +2328,11 @@ compute_parallel_delay(void)
23192328
/* Compute the total local balance for the current worker */
23202329
VacuumCostBalanceLocal += VacuumCostBalance;
23212330

2322-
if ((shared_balance >= VacuumCostLimit) &&
2323-
(VacuumCostBalanceLocal > 0.5 * ((double) VacuumCostLimit / nworkers)))
2331+
if ((shared_balance >= vacuum_cost_limit) &&
2332+
(VacuumCostBalanceLocal > 0.5 * ((double) vacuum_cost_limit / nworkers)))
23242333
{
23252334
/* Compute sleep time based on the local cost balance */
2326-
msec = VacuumCostDelay * VacuumCostBalanceLocal / VacuumCostLimit;
2335+
msec = vacuum_cost_delay * VacuumCostBalanceLocal / vacuum_cost_limit;
23272336
pg_atomic_sub_fetch_u32(VacuumSharedCostBalance, VacuumCostBalanceLocal);
23282337
VacuumCostBalanceLocal = 0;
23292338
}

src/backend/commands/vacuumparallel.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,8 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
995995
false);
996996

997997
/* Set cost-based vacuum delay */
998-
VacuumCostActive = (VacuumCostDelay > 0);
998+
VacuumCostActive = (vacuum_cost_delay > 0);
999+
VacuumUpdateCosts();
9991000
VacuumCostBalance = 0;
10001001
VacuumPageHit = 0;
10011002
VacuumPageMiss = 0;

src/backend/postmaster/autovacuum.c

+14-20
Original file line numberDiff line numberDiff line change
@@ -1773,16 +1773,24 @@ FreeWorkerInfo(int code, Datum arg)
17731773
}
17741774

17751775
/*
1776-
* Update the cost-based delay parameters, so that multiple workers consume
1777-
* each a fraction of the total available I/O.
1776+
* Update vacuum cost-based delay-related parameters for autovacuum workers and
1777+
* backends executing VACUUM or ANALYZE using the value of relevant GUCs and
1778+
* global state. This must be called during setup for vacuum and after every
1779+
* config reload to ensure up-to-date values.
17781780
*/
17791781
void
1780-
AutoVacuumUpdateDelay(void)
1782+
VacuumUpdateCosts(void)
17811783
{
17821784
if (MyWorkerInfo)
17831785
{
1784-
VacuumCostDelay = MyWorkerInfo->wi_cost_delay;
1785-
VacuumCostLimit = MyWorkerInfo->wi_cost_limit;
1786+
vacuum_cost_delay = MyWorkerInfo->wi_cost_delay;
1787+
vacuum_cost_limit = MyWorkerInfo->wi_cost_limit;
1788+
}
1789+
else
1790+
{
1791+
/* Must be explicit VACUUM or ANALYZE */
1792+
vacuum_cost_delay = VacuumCostDelay;
1793+
vacuum_cost_limit = VacuumCostLimit;
17861794
}
17871795
}
17881796

@@ -2311,8 +2319,6 @@ do_autovacuum(void)
23112319
autovac_table *tab;
23122320
bool isshared;
23132321
bool skipit;
2314-
double stdVacuumCostDelay;
2315-
int stdVacuumCostLimit;
23162322
dlist_iter iter;
23172323

23182324
CHECK_FOR_INTERRUPTS();
@@ -2415,14 +2421,6 @@ do_autovacuum(void)
24152421
continue;
24162422
}
24172423

2418-
/*
2419-
* Remember the prevailing values of the vacuum cost GUCs. We have to
2420-
* restore these at the bottom of the loop, else we'll compute wrong
2421-
* values in the next iteration of autovac_balance_cost().
2422-
*/
2423-
stdVacuumCostDelay = VacuumCostDelay;
2424-
stdVacuumCostLimit = VacuumCostLimit;
2425-
24262424
/* Must hold AutovacuumLock while mucking with cost balance info */
24272425
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
24282426

@@ -2436,7 +2434,7 @@ do_autovacuum(void)
24362434
autovac_balance_cost();
24372435

24382436
/* set the active cost parameters from the result of that */
2439-
AutoVacuumUpdateDelay();
2437+
VacuumUpdateCosts();
24402438

24412439
/* done */
24422440
LWLockRelease(AutovacuumLock);
@@ -2533,10 +2531,6 @@ do_autovacuum(void)
25332531
MyWorkerInfo->wi_tableoid = InvalidOid;
25342532
MyWorkerInfo->wi_sharedrel = false;
25352533
LWLockRelease(AutovacuumScheduleLock);
2536-
2537-
/* restore vacuum cost GUCs for the next iteration */
2538-
VacuumCostDelay = stdVacuumCostDelay;
2539-
VacuumCostLimit = stdVacuumCostLimit;
25402534
}
25412535

25422536
/*

src/include/commands/vacuum.h

+5
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ extern PGDLLIMPORT pg_atomic_uint32 *VacuumActiveNWorkers;
307307
extern PGDLLIMPORT int VacuumCostBalanceLocal;
308308

309309
extern PGDLLIMPORT bool VacuumFailsafeActive;
310+
extern PGDLLIMPORT double vacuum_cost_delay;
311+
extern PGDLLIMPORT int vacuum_cost_limit;
310312

311313
/* in commands/vacuum.c */
312314
extern void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel);
@@ -347,6 +349,9 @@ extern IndexBulkDeleteResult *vac_cleanup_one_index(IndexVacuumInfo *ivinfo,
347349
IndexBulkDeleteResult *istat);
348350
extern Size vac_max_items_to_alloc_size(int max_items);
349351

352+
/* In postmaster/autovacuum.c */
353+
extern void VacuumUpdateCosts(void);
354+
350355
/* in commands/vacuumparallel.c */
351356
extern ParallelVacuumState *parallel_vacuum_init(Relation rel, Relation *indrels,
352357
int nindexes, int nrequested_workers,

src/include/postmaster/autovacuum.h

-3
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ extern int StartAutoVacWorker(void);
6363
/* called from postmaster when a worker could not be forked */
6464
extern void AutoVacWorkerFailed(void);
6565

66-
/* autovacuum cost-delay balancer */
67-
extern void AutoVacuumUpdateDelay(void);
68-
6966
#ifdef EXEC_BACKEND
7067
extern void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_noreturn();
7168
extern void AutoVacWorkerMain(int argc, char *argv[]) pg_attribute_noreturn();

0 commit comments

Comments
 (0)