Skip to content

Commit 7d71d3d

Browse files
Refresh cost-based delay params more frequently in autovacuum
Allow autovacuum to reload the config file more often so that cost-based delay parameters can take effect while VACUUMing a relation. Previously, autovacuum workers only reloaded the config file once per relation vacuumed, so config changes could not take effect until beginning to vacuum the next table. Now, check if a reload is pending roughly once per block, when checking if we need to delay. In order for autovacuum workers to safely update their own cost delay and cost limit parameters without impacting performance, we had to rethink when and how these values were accessed. Previously, an autovacuum worker's wi_cost_limit was set only at the beginning of vacuuming a table, after reloading the config file. Therefore, at the time that autovac_balance_cost() was called, workers vacuuming tables with no cost-related storage parameters could still have different values for their wi_cost_limit_base and wi_cost_delay. Now that the cost parameters can be updated while vacuuming a table, workers will (within some margin of error) have no reason to have different values for cost limit and cost delay (in the absence of cost-related storage parameters). This removes the rationale for keeping cost limit and cost delay in shared memory. Balancing the cost limit requires only the number of active autovacuum workers vacuuming a table with no cost-based storage parameters. 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 a85c60a commit 7d71d3d

File tree

5 files changed

+219
-122
lines changed

5 files changed

+219
-122
lines changed

src/backend/access/heap/vacuumlazy.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
389389
Assert(params->index_cleanup != VACOPTVALUE_UNSPECIFIED);
390390
Assert(params->truncate != VACOPTVALUE_UNSPECIFIED &&
391391
params->truncate != VACOPTVALUE_AUTO);
392-
VacuumFailsafeActive = false;
392+
Assert(!VacuumFailsafeActive);
393393
vacrel->consider_bypass_optimization = true;
394394
vacrel->do_index_vacuuming = true;
395395
vacrel->do_index_cleanup = true;

src/backend/commands/vacuum.c

+42-4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "pgstat.h"
4949
#include "postmaster/autovacuum.h"
5050
#include "postmaster/bgworker_internals.h"
51+
#include "postmaster/interrupt.h"
5152
#include "storage/bufmgr.h"
5253
#include "storage/lmgr.h"
5354
#include "storage/pmsignal.h"
@@ -523,9 +524,9 @@ vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy,
523524
{
524525
ListCell *cur;
525526

526-
VacuumUpdateCosts();
527527
in_vacuum = true;
528-
VacuumCostActive = (vacuum_cost_delay > 0);
528+
VacuumFailsafeActive = false;
529+
VacuumUpdateCosts();
529530
VacuumCostBalance = 0;
530531
VacuumPageHit = 0;
531532
VacuumPageMiss = 0;
@@ -579,12 +580,20 @@ vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy,
579580
CommandCounterIncrement();
580581
}
581582
}
583+
584+
/*
585+
* Ensure VacuumFailsafeActive has been reset before vacuuming the
586+
* next relation.
587+
*/
588+
VacuumFailsafeActive = false;
582589
}
583590
}
584591
PG_FINALLY();
585592
{
586593
in_vacuum = false;
587594
VacuumCostActive = false;
595+
VacuumFailsafeActive = false;
596+
VacuumCostBalance = 0;
588597
}
589598
PG_END_TRY();
590599

@@ -2245,7 +2254,28 @@ vacuum_delay_point(void)
22452254
/* Always check for interrupts */
22462255
CHECK_FOR_INTERRUPTS();
22472256

2248-
if (!VacuumCostActive || InterruptPending)
2257+
if (InterruptPending ||
2258+
(!VacuumCostActive && !ConfigReloadPending))
2259+
return;
2260+
2261+
/*
2262+
* Autovacuum workers should reload the configuration file if requested.
2263+
* This allows changes to [autovacuum_]vacuum_cost_limit and
2264+
* [autovacuum_]vacuum_cost_delay to take effect while a table is being
2265+
* vacuumed or analyzed.
2266+
*/
2267+
if (ConfigReloadPending && IsAutoVacuumWorkerProcess())
2268+
{
2269+
ConfigReloadPending = false;
2270+
ProcessConfigFile(PGC_SIGHUP);
2271+
VacuumUpdateCosts();
2272+
}
2273+
2274+
/*
2275+
* If we disabled cost-based delays after reloading the config file,
2276+
* return.
2277+
*/
2278+
if (!VacuumCostActive)
22492279
return;
22502280

22512281
/*
@@ -2278,7 +2308,15 @@ vacuum_delay_point(void)
22782308

22792309
VacuumCostBalance = 0;
22802310

2281-
VacuumUpdateCosts();
2311+
/*
2312+
* Balance and update limit values for autovacuum workers. We must do
2313+
* this periodically, as the number of workers across which we are
2314+
* balancing the limit may have changed.
2315+
*
2316+
* TODO: There may be better criteria for determining when to do this
2317+
* besides "check after napping".
2318+
*/
2319+
AutoVacuumUpdateCostLimit();
22822320

22832321
/* Might have gotten an interrupt while sleeping */
22842322
CHECK_FOR_INTERRUPTS();

src/backend/commands/vacuumparallel.c

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

997997
/* Set cost-based vacuum delay */
998-
VacuumCostActive = (vacuum_cost_delay > 0);
999998
VacuumUpdateCosts();
1000999
VacuumCostBalance = 0;
10011000
VacuumPageHit = 0;

0 commit comments

Comments
 (0)