Make vacuum failsafe_active globally visible
authorDaniel Gustafsson <[email protected]>
Thu, 6 Apr 2023 22:54:08 +0000 (00:54 +0200)
committerDaniel Gustafsson <[email protected]>
Thu, 6 Apr 2023 22:54:08 +0000 (00:54 +0200)
While vacuuming a table in failsafe mode, VacuumCostActive should
not be re-enabled.  This currently isn't a problem because vacuum
cost parameters are only refreshed in between vacuuming tables and
failsafe status is reset for every table.

In preparation for allowing vacuum cost parameters to be updated
more frequently, elevate LVRelState->failsafe_active to a global,
VacuumFailsafeActive, which will be checked when determining whether
or not to re-enable vacuum cost-related delays.

Author: Melanie Plageman <[email protected]>
Reviewed-by: Masahiko Sawada <[email protected]>
Reviewed-by: Daniel Gustafsson <[email protected]>
Reviewed-by: Kyotaro Horiguchi <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://www.postgresql.org/message-id/flat/CAAKRu_ZngzqnEODc7LmS1NH04Kt6Y9huSjz5pp7%2BDXhrjDA0gw%40mail.gmail.com

src/backend/access/heap/vacuumlazy.c
src/backend/commands/vacuum.c
src/include/commands/vacuum.h

index 639179aa46d9969a6a78df8c4d0b3719e225ba2c..2ba85bd3d6de3234aaa125a1b2bff3dfc7b53666 100644 (file)
@@ -153,8 +153,6 @@ typedef struct LVRelState
    bool        aggressive;
    /* Use visibility map to skip? (disabled by DISABLE_PAGE_SKIPPING) */
    bool        skipwithvm;
-   /* Wraparound failsafe has been triggered? */
-   bool        failsafe_active;
    /* Consider index vacuuming bypass optimization? */
    bool        consider_bypass_optimization;
 
@@ -391,7 +389,7 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
    Assert(params->index_cleanup != VACOPTVALUE_UNSPECIFIED);
    Assert(params->truncate != VACOPTVALUE_UNSPECIFIED &&
           params->truncate != VACOPTVALUE_AUTO);
-   vacrel->failsafe_active = false;
+   VacuumFailsafeActive = false;
    vacrel->consider_bypass_optimization = true;
    vacrel->do_index_vacuuming = true;
    vacrel->do_index_cleanup = true;
@@ -709,7 +707,7 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
            }
            else
            {
-               if (!vacrel->failsafe_active)
+               if (!VacuumFailsafeActive)
                    appendStringInfoString(&buf, _("index scan bypassed: "));
                else
                    appendStringInfoString(&buf, _("index scan bypassed by failsafe: "));
@@ -2293,7 +2291,7 @@ lazy_vacuum(LVRelState *vacrel)
         * vacuuming or heap vacuuming.  This VACUUM operation won't end up
         * back here again.
         */
-       Assert(vacrel->failsafe_active);
+       Assert(VacuumFailsafeActive);
    }
 
    /*
@@ -2374,7 +2372,7 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
     */
    Assert(vacrel->num_index_scans > 0 ||
           vacrel->dead_items->num_items == vacrel->lpdead_items);
-   Assert(allindexes || vacrel->failsafe_active);
+   Assert(allindexes || VacuumFailsafeActive);
 
    /*
     * Increase and report the number of index scans.
@@ -2616,12 +2614,12 @@ static bool
 lazy_check_wraparound_failsafe(LVRelState *vacrel)
 {
    /* Don't warn more than once per VACUUM */
-   if (vacrel->failsafe_active)
+   if (VacuumFailsafeActive)
        return true;
 
    if (unlikely(vacuum_xid_failsafe_check(&vacrel->cutoffs)))
    {
-       vacrel->failsafe_active = true;
+       VacuumFailsafeActive = true;
 
        /*
         * Abandon use of a buffer access strategy to allow use of all of
@@ -2820,7 +2818,7 @@ should_attempt_truncation(LVRelState *vacrel)
 {
    BlockNumber possibly_freeable;
 
-   if (!vacrel->do_rel_truncate || vacrel->failsafe_active ||
+   if (!vacrel->do_rel_truncate || VacuumFailsafeActive ||
        old_snapshot_threshold >= 0)
        return false;
 
index ea1d8960f4ce26c9fa3de8c4f9d6d95d9b0f1224..7fc5c19e3797b94ab204926a7eb4d0b0364a167b 100644 (file)
@@ -72,6 +72,21 @@ int          vacuum_multixact_freeze_table_age;
 int            vacuum_failsafe_age;
 int            vacuum_multixact_failsafe_age;
 
+/*
+ * VacuumFailsafeActive is a defined as a global so that we can determine
+ * whether or not to re-enable cost-based vacuum delay when vacuuming a table.
+ * If failsafe mode has been engaged, we will not re-enable cost-based delay
+ * for the table until after vacuuming has completed, regardless of other
+ * settings.
+ *
+ * Only VACUUM code should inspect this variable and only table access methods
+ * should set it to true. In Table AM-agnostic VACUUM code, this variable is
+ * inspected to determine whether or not to allow cost-based delays. Table AMs
+ * are free to set it if they desire this behavior, but it is false by default
+ * and reset to false in between vacuuming each relation.
+ */
+bool       VacuumFailsafeActive = false;
+
 /*
  * Variables for cost-based parallel vacuum.  See comments atop
  * compute_parallel_delay to understand how it works.
index 19ca818dc206a4cb7b1d96c8385ed32fe5fe91ca..1223d15e0db86a5b84319ddead7bf5b922f3658d 100644 (file)
@@ -306,6 +306,7 @@ extern PGDLLIMPORT pg_atomic_uint32 *VacuumSharedCostBalance;
 extern PGDLLIMPORT pg_atomic_uint32 *VacuumActiveNWorkers;
 extern PGDLLIMPORT int VacuumCostBalanceLocal;
 
+extern PGDLLIMPORT bool VacuumFailsafeActive;
 
 /* in commands/vacuum.c */
 extern void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel);