diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index d692308cf494f61266bbf95d69db8c2fd33f3b76..8764e0091ac55681f71e965062c3a1b1b42e3e56 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -792,10 +792,13 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu </para> <para> - When multiple workers are running, the cost limit is + When multiple workers are running, the cost delay parameters are <quote>balanced</quote> among all the running workers, so that the - total impact on the system is the same, regardless of the number - of workers actually running. + total I/O impact on the system is the same regardless of the number + of workers actually running. However, any workers processing tables whose + <literal>autovacuum_vacuum_cost_delay</> or + <literal>autovacuum_vacuum_cost_limit</> have been set are not considered + in the balancing algorithm. </para> </sect2> </sect1> diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index c240d2444c8bfd41fb59b4cce6694e2f3434ec66..1d6e3f35f94a67fec37b38c7991c2b40a4132dfa 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -193,6 +193,7 @@ typedef struct autovac_table int at_multixact_freeze_table_age; int at_vacuum_cost_delay; int at_vacuum_cost_limit; + bool at_dobalance; bool at_wraparound; char *at_relname; char *at_nspname; @@ -223,6 +224,7 @@ typedef struct WorkerInfoData Oid wi_tableoid; PGPROC *wi_proc; TimestampTz wi_launchtime; + bool wi_dobalance; int wi_cost_delay; int wi_cost_limit; int wi_cost_limit_base; @@ -1716,6 +1718,7 @@ FreeWorkerInfo(int code, Datum arg) MyWorkerInfo->wi_tableoid = InvalidOid; MyWorkerInfo->wi_proc = NULL; MyWorkerInfo->wi_launchtime = 0; + MyWorkerInfo->wi_dobalance = false; MyWorkerInfo->wi_cost_delay = 0; MyWorkerInfo->wi_cost_limit = 0; MyWorkerInfo->wi_cost_limit_base = 0; @@ -1776,17 +1779,19 @@ autovac_balance_cost(void) if (vac_cost_limit <= 0 || vac_cost_delay <= 0) return; - /* caculate the total base cost limit of active workers */ + /* calculate the total base cost limit of participating active workers */ cost_total = 0.0; dlist_foreach(iter, &AutoVacuumShmem->av_runningWorkers) { WorkerInfo worker = dlist_container(WorkerInfoData, wi_links, iter.cur); if (worker->wi_proc != NULL && + worker->wi_dobalance && worker->wi_cost_limit_base > 0 && worker->wi_cost_delay > 0) cost_total += (double) worker->wi_cost_limit_base / worker->wi_cost_delay; } + /* there are no cost limits -- nothing to do */ if (cost_total <= 0) return; @@ -1801,6 +1806,7 @@ autovac_balance_cost(void) WorkerInfo worker = dlist_container(WorkerInfoData, wi_links, iter.cur); if (worker->wi_proc != NULL && + worker->wi_dobalance && worker->wi_cost_limit_base > 0 && worker->wi_cost_delay > 0) { int limit = (int) @@ -1815,12 +1821,14 @@ autovac_balance_cost(void) worker->wi_cost_limit = Max(Min(limit, worker->wi_cost_limit_base), 1); + } - elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, cost_limit=%d, cost_limit_base=%d, cost_delay=%d)", + if (worker->wi_proc != NULL) + elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, dobalance=%s cost_limit=%d, cost_limit_base=%d, cost_delay=%d)", worker->wi_proc->pid, worker->wi_dboid, worker->wi_tableoid, + worker->wi_dobalance ? "yes" : "no", worker->wi_cost_limit, worker->wi_cost_limit_base, worker->wi_cost_delay); - } } } @@ -2284,6 +2292,7 @@ do_autovacuum(void) LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE); /* advertise my cost delay parameters for the balancing algorithm */ + MyWorkerInfo->wi_dobalance = tab->at_dobalance; MyWorkerInfo->wi_cost_delay = tab->at_vacuum_cost_delay; MyWorkerInfo->wi_cost_limit = tab->at_vacuum_cost_limit; MyWorkerInfo->wi_cost_limit_base = tab->at_vacuum_cost_limit; @@ -2579,6 +2588,14 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, tab->at_relname = NULL; tab->at_nspname = NULL; tab->at_datname = NULL; + + /* + * If any of the cost delay parameters has been set individually for + * this table, disable the balancing algorithm. + */ + tab->at_dobalance = + !(avopts && (avopts->vacuum_cost_limit > 0 || + avopts->vacuum_cost_delay > 0)); } heap_freetuple(classTup);