Add log_min_autovacuum_duration per-table option

This is useful to control autovacuum log volume, for situations where
monitoring only a set of tables is necessary.

Author: Michael Paquier
Reviewed by: A team led by Naoya Anzai (also including Akira Kurosawa,
Taiki Kondo, Huong Dangminh), Fujii Masao.
This commit is contained in:
Alvaro Herrera 2015-04-03 11:55:50 -03:00
parent a75fb9b335
commit 4ff695b17d
9 changed files with 63 additions and 24 deletions

View File

@ -881,9 +881,9 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
<literal>toast.</literal>, which can be used to control the behavior of the
table's secondary <acronym>TOAST</> table, if any
(see <xref linkend="storage-toast"> for more information about TOAST).
Note that the TOAST table inherits the
<literal>autovacuum_*</literal> values from its parent table, if there are
no <literal>toast.autovacuum_*</literal> settings set.
Note that the TOAST table uses the parameter values defined for
the main table, for each parameter applicable to TOAST tables and
for which no value is set in the TOAST table itself.
</para>
<variablelist>
@ -1060,6 +1060,15 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
</listitem>
</varlistentry>
<varlistentry>
<term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>)</term>
<listitem>
<para>
Custom <xref linkend="guc-log-autovacuum-min-duration"> parameter.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>user_catalog_table</literal> (<type>boolean</type>)</term>
<listitem>
@ -1067,6 +1076,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
Declare a table as an additional catalog table, e.g. for the purpose of
logical replication. See
<xref linkend="logicaldecoding-capabilities"> for details.
This parameter cannot be set for TOAST tables.
</para>
</listitem>
</varlistentry>

View File

@ -209,6 +209,14 @@ static relopt_int intRelOpts[] =
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
}, -1, 0, 2000000000
},
{
{
"log_autovacuum_min_duration",
"Sets the minimum execution time above which autovacuum actions will be logged",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
-1, -1, INT_MAX
},
{
{
"pages_per_range",
@ -1210,6 +1218,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, multixact_freeze_max_age)},
{"autovacuum_multixact_freeze_table_age", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, multixact_freeze_table_age)},
{"log_autovacuum_min_duration", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, log_min_duration)},
{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, vacuum_scale_factor)},
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,

View File

@ -85,7 +85,8 @@ static MemoryContext anl_context = NULL;
static BufferAccessStrategy vac_strategy;
static void do_analyze_rel(Relation onerel, int options, List *va_cols,
static void do_analyze_rel(Relation onerel, int options,
VacuumParams *params, List *va_cols,
AcquireSampleRowsFunc acquirefunc, BlockNumber relpages,
bool inh, bool in_outer_xact, int elevel);
static void BlockSampler_Init(BlockSampler bs, BlockNumber nblocks,
@ -115,8 +116,9 @@ static Datum ind_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull);
* analyze_rel() -- analyze one relation
*/
void
analyze_rel(Oid relid, RangeVar *relation, int options, List *va_cols,
bool in_outer_xact, BufferAccessStrategy bstrategy)
analyze_rel(Oid relid, RangeVar *relation, int options,
VacuumParams *params, List *va_cols, bool in_outer_xact,
BufferAccessStrategy bstrategy)
{
Relation onerel;
int elevel;
@ -151,7 +153,7 @@ analyze_rel(Oid relid, RangeVar *relation, int options, List *va_cols,
else
{
onerel = NULL;
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
ereport(LOG,
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
errmsg("skipping analyze of \"%s\" --- lock not available",
@ -266,14 +268,14 @@ analyze_rel(Oid relid, RangeVar *relation, int options, List *va_cols,
/*
* Do the normal non-recursive ANALYZE.
*/
do_analyze_rel(onerel, options, va_cols, acquirefunc, relpages,
do_analyze_rel(onerel, options, params, va_cols, acquirefunc, relpages,
false, in_outer_xact, elevel);
/*
* If there are child tables, do recursive ANALYZE.
*/
if (onerel->rd_rel->relhassubclass)
do_analyze_rel(onerel, options, va_cols, acquirefunc, relpages,
do_analyze_rel(onerel, options, params, va_cols, acquirefunc, relpages,
true, in_outer_xact, elevel);
/*
@ -301,9 +303,10 @@ analyze_rel(Oid relid, RangeVar *relation, int options, List *va_cols,
* appropriate acquirefunc for each child table.
*/
static void
do_analyze_rel(Relation onerel, int options, List *va_cols,
AcquireSampleRowsFunc acquirefunc, BlockNumber relpages,
bool inh, bool in_outer_xact, int elevel)
do_analyze_rel(Relation onerel, int options, VacuumParams *params,
List *va_cols, AcquireSampleRowsFunc acquirefunc,
BlockNumber relpages, bool inh, bool in_outer_xact,
int elevel)
{
int attr_cnt,
tcnt,
@ -359,10 +362,10 @@ do_analyze_rel(Relation onerel, int options, List *va_cols,
save_nestlevel = NewGUCNestLevel();
/* measure elapsed time iff autovacuum logging requires it */
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
{
pg_rusage_init(&ru0);
if (Log_autovacuum_min_duration > 0)
if (params->log_min_duration > 0)
starttime = GetCurrentTimestamp();
}
@ -647,11 +650,11 @@ do_analyze_rel(Relation onerel, int options, List *va_cols,
vac_close_indexes(nindexes, Irel, NoLock);
/* Log the action if appropriate */
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
{
if (Log_autovacuum_min_duration == 0 ||
if (params->log_min_duration == 0 ||
TimestampDifferenceExceeds(starttime, GetCurrentTimestamp(),
Log_autovacuum_min_duration))
params->log_min_duration))
ereport(LOG,
(errmsg("automatic analyze of table \"%s.%s.%s\" system usage: %s",
get_database_name(MyDatabaseId),

View File

@ -114,6 +114,9 @@ ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel)
/* user-invoked vacuum is never "for wraparound" */
params.is_wraparound = false;
/* user-invoked vacuum never uses this parameter */
params.log_min_duration = -1;
/* Now go through the common routine */
vacuum(vacstmt->options, vacstmt->relation, InvalidOid, &params,
vacstmt->va_cols, NULL, isTopLevel);
@ -304,7 +307,7 @@ vacuum(int options, RangeVar *relation, Oid relid, VacuumParams *params,
PushActiveSnapshot(GetTransactionSnapshot());
}
analyze_rel(relid, relation, options,
analyze_rel(relid, relation, options, params,
va_cols, in_outer_xact, vac_strategy);
if (use_own_xacts)
@ -1233,7 +1236,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
else
{
onerel = NULL;
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
ereport(LOG,
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
errmsg("skipping vacuum of \"%s\" --- lock not available",

View File

@ -196,7 +196,7 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params,
Assert(params != NULL);
/* measure elapsed time iff autovacuum logging requires it */
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
{
pg_rusage_init(&ru0);
starttime = GetCurrentTimestamp();
@ -328,13 +328,13 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params,
vacrelstats->new_dead_tuples);
/* and log the action if appropriate */
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
{
TimestampTz endtime = GetCurrentTimestamp();
if (Log_autovacuum_min_duration == 0 ||
if (params->log_min_duration == 0 ||
TimestampDifferenceExceeds(starttime, endtime,
Log_autovacuum_min_duration))
params->log_min_duration))
{
StringInfoData buf;
TimestampDifference(starttime, endtime, &secs, &usecs);

View File

@ -2493,6 +2493,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int vac_cost_limit;
int vac_cost_delay;
int log_min_duration;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@ -2515,6 +2516,11 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? autovacuum_vac_cost_limit
: VacuumCostLimit;
/* -1 in autovac setting means use log_autovacuum_min_duration */
log_min_duration = (avopts && avopts->log_min_duration >= 0)
? avopts->log_min_duration
: Log_autovacuum_min_duration;
/* these do not have autovacuum-specific settings */
freeze_min_age = (avopts && avopts->freeze_min_age >= 0)
? avopts->freeze_min_age
@ -2545,6 +2551,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.multixact_freeze_min_age = multixact_freeze_min_age;
tab->at_params.multixact_freeze_table_age = multixact_freeze_table_age;
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_vacuum_cost_limit = vac_cost_limit;
tab->at_vacuum_cost_delay = vac_cost_delay;
tab->at_relname = NULL;

View File

@ -1788,6 +1788,7 @@ psql_completion(const char *text, int start, int end)
"autovacuum_vacuum_scale_factor",
"autovacuum_vacuum_threshold",
"fillfactor",
"log_autovacuum_min_duration",
"toast.autovacuum_enabled",
"toast.autovacuum_freeze_max_age",
"toast.autovacuum_freeze_min_age",
@ -1799,6 +1800,7 @@ psql_completion(const char *text, int start, int end)
"toast.autovacuum_vacuum_cost_limit",
"toast.autovacuum_vacuum_scale_factor",
"toast.autovacuum_vacuum_threshold",
"toast.log_autovacuum_min_duration",
"user_catalog_table",
NULL
};

View File

@ -142,6 +142,9 @@ typedef struct VacuumParams
int multixact_freeze_table_age; /* multixact age at which to
* scan whole table */
bool is_wraparound; /* force a for-wraparound vacuum */
int log_min_duration; /* minimum execution threshold in ms at
* which verbose logs are activated,
* -1 to use default */
} VacuumParams;
/* GUC parameters */
@ -191,7 +194,7 @@ extern void lazy_vacuum_rel(Relation onerel, int options,
/* in commands/analyze.c */
extern void analyze_rel(Oid relid, RangeVar *relation, int options,
List *va_cols, bool in_outer_xact,
VacuumParams *params, List *va_cols, bool in_outer_xact,
BufferAccessStrategy bstrategy);
extern bool std_typanalyze(VacAttrStats *stats);
extern double anl_random_fract(void);

View File

@ -209,6 +209,7 @@ typedef struct AutoVacOpts
int multixact_freeze_min_age;
int multixact_freeze_max_age;
int multixact_freeze_table_age;
int log_min_duration;
float8 vacuum_scale_factor;
float8 analyze_scale_factor;
} AutoVacOpts;