Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1021bd6

Browse files
committed
Don't balance vacuum cost delay when per-table settings are in effect
When there are cost-delay-related storage options set for a table, trying to make that table participate in the autovacuum cost-limit balancing algorithm produces undesirable results: instead of using the configured values, the global values are always used, as illustrated by Mark Kirkwood in http://www.postgresql.org/message-id/52FACF15.8020507@catalyst.net.nz Since the mechanism is already complicated, just disable it for those cases rather than trying to make it cope. There are undesirable side-effects from this too, namely that the total I/O impact on the system will be higher whenever such tables are vacuumed. However, this is seen as less harmful than slowing down vacuum, because that would cause bloat to accumulate. Anyway, in the new system it is possible to tweak options to get the precise behavior one wants, whereas with the previous system one was simply hosed. This has been broken forever, so backpatch to all supported branches. This might affect systems where cost_limit and cost_delay have been set for individual tables.
1 parent 017b2e9 commit 1021bd6

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

doc/src/sgml/maintenance.sgml

+6-3
Original file line numberDiff line numberDiff line change
@@ -792,10 +792,13 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
792792
</para>
793793

794794
<para>
795-
When multiple workers are running, the cost limit is
795+
When multiple workers are running, the cost delay parameters are
796796
<quote>balanced</quote> among all the running workers, so that the
797-
total impact on the system is the same, regardless of the number
798-
of workers actually running.
797+
total I/O impact on the system is the same regardless of the number
798+
of workers actually running. However, any workers processing tables whose
799+
<literal>autovacuum_vacuum_cost_delay</> or
800+
<literal>autovacuum_vacuum_cost_limit</> have been set are not considered
801+
in the balancing algorithm.
799802
</para>
800803
</sect2>
801804
</sect1>

src/backend/postmaster/autovacuum.c

+20-3
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ typedef struct autovac_table
193193
int at_multixact_freeze_table_age;
194194
int at_vacuum_cost_delay;
195195
int at_vacuum_cost_limit;
196+
bool at_dobalance;
196197
bool at_wraparound;
197198
char *at_relname;
198199
char *at_nspname;
@@ -223,6 +224,7 @@ typedef struct WorkerInfoData
223224
Oid wi_tableoid;
224225
PGPROC *wi_proc;
225226
TimestampTz wi_launchtime;
227+
bool wi_dobalance;
226228
int wi_cost_delay;
227229
int wi_cost_limit;
228230
int wi_cost_limit_base;
@@ -1716,6 +1718,7 @@ FreeWorkerInfo(int code, Datum arg)
17161718
MyWorkerInfo->wi_tableoid = InvalidOid;
17171719
MyWorkerInfo->wi_proc = NULL;
17181720
MyWorkerInfo->wi_launchtime = 0;
1721+
MyWorkerInfo->wi_dobalance = false;
17191722
MyWorkerInfo->wi_cost_delay = 0;
17201723
MyWorkerInfo->wi_cost_limit = 0;
17211724
MyWorkerInfo->wi_cost_limit_base = 0;
@@ -1776,17 +1779,19 @@ autovac_balance_cost(void)
17761779
if (vac_cost_limit <= 0 || vac_cost_delay <= 0)
17771780
return;
17781781

1779-
/* caculate the total base cost limit of active workers */
1782+
/* calculate the total base cost limit of participating active workers */
17801783
cost_total = 0.0;
17811784
dlist_foreach(iter, &AutoVacuumShmem->av_runningWorkers)
17821785
{
17831786
WorkerInfo worker = dlist_container(WorkerInfoData, wi_links, iter.cur);
17841787

17851788
if (worker->wi_proc != NULL &&
1789+
worker->wi_dobalance &&
17861790
worker->wi_cost_limit_base > 0 && worker->wi_cost_delay > 0)
17871791
cost_total +=
17881792
(double) worker->wi_cost_limit_base / worker->wi_cost_delay;
17891793
}
1794+
17901795
/* there are no cost limits -- nothing to do */
17911796
if (cost_total <= 0)
17921797
return;
@@ -1801,6 +1806,7 @@ autovac_balance_cost(void)
18011806
WorkerInfo worker = dlist_container(WorkerInfoData, wi_links, iter.cur);
18021807

18031808
if (worker->wi_proc != NULL &&
1809+
worker->wi_dobalance &&
18041810
worker->wi_cost_limit_base > 0 && worker->wi_cost_delay > 0)
18051811
{
18061812
int limit = (int)
@@ -1815,12 +1821,14 @@ autovac_balance_cost(void)
18151821
worker->wi_cost_limit = Max(Min(limit,
18161822
worker->wi_cost_limit_base),
18171823
1);
1824+
}
18181825

1819-
elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, cost_limit=%d, cost_limit_base=%d, cost_delay=%d)",
1826+
if (worker->wi_proc != NULL)
1827+
elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, dobalance=%s cost_limit=%d, cost_limit_base=%d, cost_delay=%d)",
18201828
worker->wi_proc->pid, worker->wi_dboid, worker->wi_tableoid,
1829+
worker->wi_dobalance ? "yes" : "no",
18211830
worker->wi_cost_limit, worker->wi_cost_limit_base,
18221831
worker->wi_cost_delay);
1823-
}
18241832
}
18251833
}
18261834

@@ -2284,6 +2292,7 @@ do_autovacuum(void)
22842292
LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
22852293

22862294
/* advertise my cost delay parameters for the balancing algorithm */
2295+
MyWorkerInfo->wi_dobalance = tab->at_dobalance;
22872296
MyWorkerInfo->wi_cost_delay = tab->at_vacuum_cost_delay;
22882297
MyWorkerInfo->wi_cost_limit = tab->at_vacuum_cost_limit;
22892298
MyWorkerInfo->wi_cost_limit_base = tab->at_vacuum_cost_limit;
@@ -2579,6 +2588,14 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
25792588
tab->at_relname = NULL;
25802589
tab->at_nspname = NULL;
25812590
tab->at_datname = NULL;
2591+
2592+
/*
2593+
* If any of the cost delay parameters has been set individually for
2594+
* this table, disable the balancing algorithm.
2595+
*/
2596+
tab->at_dobalance =
2597+
!(avopts && (avopts->vacuum_cost_limit > 0 ||
2598+
avopts->vacuum_cost_delay > 0));
25822599
}
25832600

25842601
heap_freetuple(classTup);

0 commit comments

Comments
 (0)