From 124876c4fa4f17989dfa727d8bdbea49e1263db2 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 13 Jan 2015 14:06:54 +0900 Subject: [PATCH] Make log_autovacuum_min_duration a relation option This is useful to control autovacuum log spam on systems where monitoring only a set of tables is important. --- doc/src/sgml/ref/create_table.sgml | 14 ++++++++++++++ src/backend/access/common/reloptions.c | 10 ++++++++++ src/backend/commands/analyze.c | 12 ++++++------ src/backend/commands/vacuum.c | 2 +- src/backend/commands/vacuumlazy.c | 8 ++++---- src/backend/nodes/copyfuncs.c | 1 + src/backend/nodes/equalfuncs.c | 1 + src/backend/parser/gram.y | 7 +++++++ src/backend/postmaster/autovacuum.c | 22 ++++++++++++++++++++++ src/bin/psql/tab-complete.c | 2 ++ src/include/nodes/parsenodes.h | 2 ++ src/include/utils/rel.h | 1 + 12 files changed, 71 insertions(+), 11 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index 299cce8..2382459 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1052,6 +1052,20 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI + log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) + + + Custom parameter. When + this parameter is set to -1, which is the default behavior, + the value of the GUC parameter log_autovacuum_min_duration + is used. When a value of -2 is set, logging is entirely + disabled, ignoring as well the value defined by the GUC parameter + log_autovacuum_min_duration. + + + + + user_catalog_table (boolean) diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index f008fab..a975387 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -211,6 +211,14 @@ static relopt_int intRelOpts[] = }, { { + "log_autovacuum_min_duration", + "Sets the minimum execution time above which autovacuum actions will be logged", + RELOPT_KIND_HEAP | RELOPT_KIND_TOAST + }, + -1, -2, INT_MAX + }, + { + { "pages_per_range", "Number of pages that each page range covers in a BRIN index", RELOPT_KIND_BRIN @@ -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, diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index d2856a3..e939d4e 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -151,7 +151,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt, else { onerel = NULL; - if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) + if (IsAutoVacuumWorkerProcess() && vacstmt->log_min_duration >= 0) ereport(LOG, (errcode(ERRCODE_LOCK_NOT_AVAILABLE), errmsg("skipping analyze of \"%s\" --- lock not available", @@ -360,10 +360,10 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, save_nestlevel = NewGUCNestLevel(); /* measure elapsed time iff autovacuum logging requires it */ - if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) + if (IsAutoVacuumWorkerProcess() && vacstmt->log_min_duration >= 0) { pg_rusage_init(&ru0); - if (Log_autovacuum_min_duration > 0) + if (vacstmt->log_min_duration > 0) starttime = GetCurrentTimestamp(); } @@ -648,11 +648,11 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, vac_close_indexes(nindexes, Irel, NoLock); /* Log the action if appropriate */ - if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) + if (IsAutoVacuumWorkerProcess() && vacstmt->log_min_duration >= 0) { - if (Log_autovacuum_min_duration == 0 || + if (vacstmt->log_min_duration == 0 || TimestampDifferenceExceeds(starttime, GetCurrentTimestamp(), - Log_autovacuum_min_duration)) + vacstmt->log_min_duration)) ereport(LOG, (errmsg("automatic analyze of table \"%s.%s.%s\" system usage: %s", get_database_name(MyDatabaseId), diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 2f3f79d..1b91147 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -1190,7 +1190,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound) else { onerel = NULL; - if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) + if (IsAutoVacuumWorkerProcess() && vacstmt->log_min_duration >= 0) ereport(LOG, (errcode(ERRCODE_LOCK_NOT_AVAILABLE), errmsg("skipping vacuum of \"%s\" --- lock not available", diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c index 7d9e49e..afa7567 100644 --- a/src/backend/commands/vacuumlazy.c +++ b/src/backend/commands/vacuumlazy.c @@ -194,7 +194,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt, MultiXactId new_min_multi; /* measure elapsed time iff autovacuum logging requires it */ - if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) + if (IsAutoVacuumWorkerProcess() && vacstmt->log_min_duration >= 0) { pg_rusage_init(&ru0); starttime = GetCurrentTimestamp(); @@ -325,13 +325,13 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt, vacrelstats->new_dead_tuples); /* and log the action if appropriate */ - if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) + if (IsAutoVacuumWorkerProcess() && vacstmt->log_min_duration >= 0) { TimestampTz endtime = GetCurrentTimestamp(); - if (Log_autovacuum_min_duration == 0 || + if (vacstmt->log_min_duration == 0 || TimestampDifferenceExceeds(starttime, endtime, - Log_autovacuum_min_duration)) + vacstmt->log_min_duration)) { StringInfoData buf; TimestampDifference(starttime, endtime, &secs, &usecs); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index f1a24f5..f77fc76 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -3291,6 +3291,7 @@ _copyVacuumStmt(const VacuumStmt *from) COPY_SCALAR_FIELD(freeze_table_age); COPY_SCALAR_FIELD(multixact_freeze_min_age); COPY_SCALAR_FIELD(multixact_freeze_table_age); + COPY_SCALAR_FIELD(log_min_duration); COPY_NODE_FIELD(relation); COPY_NODE_FIELD(va_cols); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 6e8b308..f4b6bff 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1508,6 +1508,7 @@ _equalVacuumStmt(const VacuumStmt *a, const VacuumStmt *b) COMPARE_SCALAR_FIELD(freeze_table_age); COMPARE_SCALAR_FIELD(multixact_freeze_min_age); COMPARE_SCALAR_FIELD(multixact_freeze_table_age); + COMPARE_SCALAR_FIELD(log_min_duration); COMPARE_NODE_FIELD(relation); COMPARE_NODE_FIELD(va_cols); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 36dac29..8a3951e 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -9066,6 +9066,7 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose n->freeze_table_age = $3 ? 0 : -1; n->multixact_freeze_min_age = $3 ? 0 : -1; n->multixact_freeze_table_age = $3 ? 0 : -1; + n->log_min_duration = -1; n->relation = NULL; n->va_cols = NIL; $$ = (Node *)n; @@ -9082,6 +9083,7 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose n->freeze_table_age = $3 ? 0 : -1; n->multixact_freeze_min_age = $3 ? 0 : -1; n->multixact_freeze_table_age = $3 ? 0 : -1; + n->log_min_duration = -1; n->relation = $5; n->va_cols = NIL; $$ = (Node *)n; @@ -9098,6 +9100,7 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose n->freeze_table_age = $3 ? 0 : -1; n->multixact_freeze_min_age = $3 ? 0 : -1; n->multixact_freeze_table_age = $3 ? 0 : -1; + n->log_min_duration = -1; $$ = (Node *)n; } | VACUUM '(' vacuum_option_list ')' @@ -9116,6 +9119,7 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose n->multixact_freeze_min_age = -1; n->multixact_freeze_table_age = -1; } + n->log_min_duration = -1; n->relation = NULL; n->va_cols = NIL; $$ = (Node *) n; @@ -9136,6 +9140,7 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose n->multixact_freeze_min_age = -1; n->multixact_freeze_table_age = -1; } + n->log_min_duration = -1; n->relation = $5; n->va_cols = $6; if (n->va_cols != NIL) /* implies analyze */ @@ -9167,6 +9172,7 @@ AnalyzeStmt: n->freeze_table_age = -1; n->multixact_freeze_min_age = -1; n->multixact_freeze_table_age = -1; + n->log_min_duration = -1; n->relation = NULL; n->va_cols = NIL; $$ = (Node *)n; @@ -9181,6 +9187,7 @@ AnalyzeStmt: n->freeze_table_age = -1; n->multixact_freeze_min_age = -1; n->multixact_freeze_table_age = -1; + n->log_min_duration = -1; n->relation = $3; n->va_cols = $4; $$ = (Node *)n; diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 77158c1..a5d73d7 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -192,6 +192,7 @@ typedef struct autovac_table int at_multixact_freeze_table_age; int at_vacuum_cost_delay; int at_vacuum_cost_limit; + int at_log_min_duration; bool at_dobalance; bool at_wraparound; char *at_relname; @@ -2485,6 +2486,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 @@ -2507,6 +2509,24 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, ? autovacuum_vac_cost_limit : VacuumCostLimit; + /* + * -1 for this setting means that the GUC equivalent + * log_autovacuum_min_duration should be used, while a value of + * -2 means that logging is entirely disabled. In other cases + * the value defined is used. + */ + log_min_duration = Log_autovacuum_min_duration; + if (avopts) + { + Assert(avopts->log_min_duration >= -2); + if (avopts->log_min_duration == -2) + log_min_duration = -1; + else if (avopts->log_min_duration == -1) + log_min_duration = Log_autovacuum_min_duration; + else + log_min_duration = avopts->log_min_duration; + } + /* these do not have autovacuum-specific settings */ freeze_min_age = (avopts && avopts->freeze_min_age >= 0) ? avopts->freeze_min_age @@ -2537,6 +2557,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, tab->at_vacuum_cost_limit = vac_cost_limit; tab->at_vacuum_cost_delay = vac_cost_delay; tab->at_wraparound = wraparound; + tab->at_log_min_duration = log_min_duration; tab->at_relname = NULL; tab->at_nspname = NULL; tab->at_datname = NULL; @@ -2762,6 +2783,7 @@ autovacuum_do_vac_analyze(autovac_table *tab, vacstmt.freeze_table_age = tab->at_freeze_table_age; vacstmt.multixact_freeze_min_age = tab->at_multixact_freeze_min_age; vacstmt.multixact_freeze_table_age = tab->at_multixact_freeze_table_age; + vacstmt.log_min_duration = tab->at_log_min_duration; /* we pass the OID, but might need this anyway for an error message */ vacstmt.relation = &rangevar; vacstmt.va_cols = NIL; diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index e39a07c..d43c114 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -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 }; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index b1dfa85..95b5e21 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2615,6 +2615,8 @@ typedef struct VacuumStmt * or -1 to use default */ int multixact_freeze_table_age; /* multixact age at which to * scan whole table */ + int log_min_duration; /* minimum threshold at which vaccum + * activity is logged */ RangeVar *relation; /* single table to process, or NULL */ List *va_cols; /* list of column names, or NIL for all */ } VacuumStmt; diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 6bd786d..9e17d87 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -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; -- 2.3.0