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:
parent
a75fb9b335
commit
4ff695b17d
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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, ¶ms,
|
||||
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",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue