Add log_min_autovacuum_duration per-table option
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 3 Apr 2015 14:55:50 +0000 (11:55 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 3 Apr 2015 14:55:50 +0000 (11:55 -0300)
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.

doc/src/sgml/ref/create_table.sgml
src/backend/access/common/reloptions.c
src/backend/commands/analyze.c
src/backend/commands/vacuum.c
src/backend/commands/vacuumlazy.c
src/backend/postmaster/autovacuum.c
src/bin/psql/tab-complete.c
src/include/commands/vacuum.h
src/include/utils/rel.h

index 324d59371a79f0a97d6ff2b00f1775d45351777e..be7ebd5f54f74db650b428eaf2ae3bbeb2b94d50 100644 (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>
index f008fab8211705a2c73917e51dd8d8039b065267..8176b6a6d414b2ac2e0dd69c1db9be4dbcb9c388 100644 (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,
index d4d19148e5736ae7e1c5f04b3b7a91b2cd4ea326..15ec0ad551cdb1bc56576bad4a235122c1523230 100644 (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),
index bd57b683d836511fd8b3d086a23ff75e85fc3479..7ead161760336221a02b10c688009e95f97ec8b3 100644 (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",
index cd5ca4c2f9735e3917b4292680609875484b50a7..c3d6e5989095736e839dc05ec62b1a53bd19e9fa 100644 (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);
index b2d37e5d4799c3c582e1c7d2d458864c51723ec1..db46134979eba8857b1d54feb54d78a54c3026c7 100644 (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;
index 5a4fd5c87315282cf2ca993df4d62c10c24b96ba..38fde39b30b9cb5e5f8f97abb85370b72d9c6a28 100644 (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
                };
index 9fd2516923051c8a15cc84cd036e2b72a2a658f9..71f016552bf33454f07bb888531530bd01b0f850 100644 (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);
index 6bd786df2d6607d3c7f076eb0ea3a680193e2f51..9e17d87413d7d7855efd7910f803f59b47a2e6cc 100644 (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;