Skip to content

Commit caf626b

Browse files
committed
Convert [autovacuum_]vacuum_cost_delay into floating-point GUCs.
This change makes it possible to specify sub-millisecond delays, which work well on most modern platforms, though that was not true when the cost-delay feature was designed. To support this without breaking existing configuration entries, improve guc.c to allow floating-point GUCs to have units. Also, allow "us" (microseconds) as an input/output unit for time-unit GUCs. (It's not allowed as a base unit, at least not yet.) Likewise change the autovacuum_vacuum_cost_delay reloption to be floating-point; this forces a catversion bump because the layout of StdRdOptions changes. This patch doesn't in itself change the default values or allowed ranges for these parameters, and it should not affect the behavior for any already-allowed setting for them. Discussion: https://postgr.es/m/1798.1552165479@sss.pgh.pa.us
1 parent 28a65fc commit caf626b

File tree

15 files changed

+246
-161
lines changed

15 files changed

+246
-161
lines changed

doc/src/sgml/config.sgml

+13-10
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@
9191

9292
<listitem>
9393
<para>
94-
Valid time units are <literal>ms</literal> (milliseconds),
94+
Valid time units are
95+
<literal>us</literal> (microseconds),
96+
<literal>ms</literal> (milliseconds),
9597
<literal>s</literal> (seconds), <literal>min</literal> (minutes),
9698
<literal>h</literal> (hours), and <literal>d</literal> (days).
9799
</para>
@@ -1845,7 +1847,7 @@ include_dir 'conf.d'
18451847

18461848
<variablelist>
18471849
<varlistentry id="guc-vacuum-cost-delay" xreflabel="vacuum_cost_delay">
1848-
<term><varname>vacuum_cost_delay</varname> (<type>integer</type>)
1850+
<term><varname>vacuum_cost_delay</varname> (<type>floating point</type>)
18491851
<indexterm>
18501852
<primary><varname>vacuum_cost_delay</varname> configuration parameter</primary>
18511853
</indexterm>
@@ -1856,18 +1858,19 @@ include_dir 'conf.d'
18561858
when the cost limit has been exceeded.
18571859
The default value is zero, which disables the cost-based vacuum
18581860
delay feature. Positive values enable cost-based vacuuming.
1859-
Note that on many systems, the effective resolution
1860-
of sleep delays is 10 milliseconds; setting
1861-
<varname>vacuum_cost_delay</varname> to a value that is
1862-
not a multiple of 10 might have the same results as setting it
1863-
to the next higher multiple of 10.
18641861
</para>
18651862

18661863
<para>
18671864
When using cost-based vacuuming, appropriate values for
18681865
<varname>vacuum_cost_delay</varname> are usually quite small, perhaps
1869-
10 or 20 milliseconds. Adjusting vacuum's resource consumption
1870-
is best done by changing the other vacuum cost parameters.
1866+
less than 1 millisecond. While <varname>vacuum_cost_delay</varname>
1867+
can be set to fractional-millisecond values, such delays may not be
1868+
measured accurately on older platforms. On such platforms,
1869+
increasing <command>VACUUM</command>'s throttled resource consumption
1870+
above what you get at 1ms will require changing the other vacuum cost
1871+
parameters. You should, nonetheless,
1872+
keep <varname>vacuum_cost_delay</varname> as small as your platform
1873+
will consistently measure; large delays are not helpful.
18711874
</para>
18721875
</listitem>
18731876
</varlistentry>
@@ -7020,7 +7023,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
70207023
</varlistentry>
70217024

70227025
<varlistentry id="guc-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay">
7023-
<term><varname>autovacuum_vacuum_cost_delay</varname> (<type>integer</type>)
7026+
<term><varname>autovacuum_vacuum_cost_delay</varname> (<type>floating point</type>)
70247027
<indexterm>
70257028
<primary><varname>autovacuum_vacuum_cost_delay</varname> configuration parameter</primary>
70267029
</indexterm>

doc/src/sgml/ref/create_table.sgml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
13851385
</varlistentry>
13861386

13871387
<varlistentry>
1388-
<term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>integer</type>)</term>
1388+
<term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>)</term>
13891389
<listitem>
13901390
<para>
13911391
Per-table value for <xref linkend="guc-autovacuum-vacuum-cost-delay"/>

src/backend/access/common/reloptions.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1198,7 +1198,7 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
11981198
{
11991199
relopt_real *optreal = (relopt_real *) option->gen;
12001200

1201-
parsed = parse_real(value, &option->values.real_val);
1201+
parsed = parse_real(value, &option->values.real_val, 0, NULL);
12021202
if (validate && !parsed)
12031203
ereport(ERROR,
12041204
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -1359,8 +1359,6 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
13591359
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_threshold)},
13601360
{"autovacuum_analyze_threshold", RELOPT_TYPE_INT,
13611361
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_threshold)},
1362-
{"autovacuum_vacuum_cost_delay", RELOPT_TYPE_INT,
1363-
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay)},
13641362
{"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT,
13651363
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_limit)},
13661364
{"autovacuum_freeze_min_age", RELOPT_TYPE_INT,
@@ -1379,6 +1377,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
13791377
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, log_min_duration)},
13801378
{"toast_tuple_target", RELOPT_TYPE_INT,
13811379
offsetof(StdRdOptions, toast_tuple_target)},
1380+
{"autovacuum_vacuum_cost_delay", RELOPT_TYPE_REAL,
1381+
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay)},
13821382
{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
13831383
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_scale_factor)},
13841384
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,

src/backend/commands/vacuum.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1834,13 +1834,13 @@ vacuum_delay_point(void)
18341834
if (VacuumCostActive && !InterruptPending &&
18351835
VacuumCostBalance >= VacuumCostLimit)
18361836
{
1837-
int msec;
1837+
double msec;
18381838

18391839
msec = VacuumCostDelay * VacuumCostBalance / VacuumCostLimit;
18401840
if (msec > VacuumCostDelay * 4)
18411841
msec = VacuumCostDelay * 4;
18421842

1843-
pg_usleep(msec * 1000L);
1843+
pg_usleep((long) (msec * 1000));
18441844

18451845
VacuumCostBalance = 0;
18461846

src/backend/postmaster/autovacuum.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ double autovacuum_anl_scale;
120120
int autovacuum_freeze_max_age;
121121
int autovacuum_multixact_freeze_max_age;
122122

123-
int autovacuum_vac_cost_delay;
123+
double autovacuum_vac_cost_delay;
124124
int autovacuum_vac_cost_limit;
125125

126126
int Log_autovacuum_min_duration = -1;
@@ -189,7 +189,7 @@ typedef struct autovac_table
189189
Oid at_relid;
190190
int at_vacoptions; /* bitmask of VacuumOption */
191191
VacuumParams at_params;
192-
int at_vacuum_cost_delay;
192+
double at_vacuum_cost_delay;
193193
int at_vacuum_cost_limit;
194194
bool at_dobalance;
195195
bool at_sharedrel;
@@ -225,7 +225,7 @@ typedef struct WorkerInfoData
225225
TimestampTz wi_launchtime;
226226
bool wi_dobalance;
227227
bool wi_sharedrel;
228-
int wi_cost_delay;
228+
double wi_cost_delay;
229229
int wi_cost_limit;
230230
int wi_cost_limit_base;
231231
} WorkerInfoData;
@@ -1785,7 +1785,7 @@ autovac_balance_cost(void)
17851785
*/
17861786
int vac_cost_limit = (autovacuum_vac_cost_limit > 0 ?
17871787
autovacuum_vac_cost_limit : VacuumCostLimit);
1788-
int vac_cost_delay = (autovacuum_vac_cost_delay >= 0 ?
1788+
double vac_cost_delay = (autovacuum_vac_cost_delay >= 0 ?
17891789
autovacuum_vac_cost_delay : VacuumCostDelay);
17901790
double cost_total;
17911791
double cost_avail;
@@ -1840,7 +1840,7 @@ autovac_balance_cost(void)
18401840
}
18411841

18421842
if (worker->wi_proc != NULL)
1843-
elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, dobalance=%s cost_limit=%d, cost_limit_base=%d, cost_delay=%d)",
1843+
elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, dobalance=%s cost_limit=%d, cost_limit_base=%d, cost_delay=%g)",
18441844
worker->wi_proc->pid, worker->wi_dboid, worker->wi_tableoid,
18451845
worker->wi_dobalance ? "yes" : "no",
18461846
worker->wi_cost_limit, worker->wi_cost_limit_base,
@@ -2302,7 +2302,7 @@ do_autovacuum(void)
23022302
autovac_table *tab;
23032303
bool isshared;
23042304
bool skipit;
2305-
int stdVacuumCostDelay;
2305+
double stdVacuumCostDelay;
23062306
int stdVacuumCostLimit;
23072307
dlist_iter iter;
23082308

@@ -2831,7 +2831,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
28312831
int multixact_freeze_min_age;
28322832
int multixact_freeze_table_age;
28332833
int vac_cost_limit;
2834-
int vac_cost_delay;
2834+
double vac_cost_delay;
28352835
int log_min_duration;
28362836

28372837
/*
@@ -2993,7 +2993,7 @@ relation_needs_vacanalyze(Oid relid,
29932993
* table), or the autovacuum GUC variables.
29942994
*/
29952995

2996-
/* -1 in autovac setting means use plain vacuum_cost_delay */
2996+
/* -1 in autovac setting means use plain vacuum_scale_factor */
29972997
vac_scale_factor = (relopts && relopts->vacuum_scale_factor >= 0)
29982998
? relopts->vacuum_scale_factor
29992999
: autovacuum_vac_scale;

src/backend/utils/init/globals.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ int VacuumCostPageHit = 1; /* GUC parameters for vacuum */
138138
int VacuumCostPageMiss = 10;
139139
int VacuumCostPageDirty = 20;
140140
int VacuumCostLimit = 2000;
141-
int VacuumCostDelay = 0;
141+
double VacuumCostDelay = 0;
142142

143143
int VacuumPageHit = 0;
144144
int VacuumPageMiss = 0;

0 commit comments

Comments
 (0)