aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/vacuum.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/vacuum.c')
-rw-r--r--src/backend/commands/vacuum.c120
1 files changed, 55 insertions, 65 deletions
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 293b84bbca8..ba965b8c7b4 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -907,34 +907,20 @@ get_all_vacuum_rels(int options)
}
/*
- * vacuum_set_xid_limits() -- compute OldestXmin and freeze cutoff points
+ * vacuum_get_cutoffs() -- compute OldestXmin and freeze cutoff points
*
* The target relation and VACUUM parameters are our inputs.
*
- * Our output parameters are:
- * - OldestXmin is the Xid below which tuples deleted by any xact (that
- * committed) should be considered DEAD, not just RECENTLY_DEAD.
- * - OldestMxact is the Mxid below which MultiXacts are definitely not
- * seen as visible by any running transaction.
- * - FreezeLimit is the Xid below which all Xids are definitely frozen or
- * removed during aggressive vacuums.
- * - MultiXactCutoff is the value below which all MultiXactIds are definitely
- * removed from Xmax during aggressive vacuums.
+ * Output parameters are the cutoffs that VACUUM caller should use.
*
* Return value indicates if vacuumlazy.c caller should make its VACUUM
* operation aggressive. An aggressive VACUUM must advance relfrozenxid up to
* FreezeLimit (at a minimum), and relminmxid up to MultiXactCutoff (at a
* minimum).
- *
- * OldestXmin and OldestMxact are the most recent values that can ever be
- * passed to vac_update_relstats() as frozenxid and minmulti arguments by our
- * vacuumlazy.c caller later on. These values should be passed when it turns
- * out that VACUUM will leave no unfrozen XIDs/MXIDs behind in the table.
*/
bool
-vacuum_set_xid_limits(Relation rel, const VacuumParams *params,
- TransactionId *OldestXmin, MultiXactId *OldestMxact,
- TransactionId *FreezeLimit, MultiXactId *MultiXactCutoff)
+vacuum_get_cutoffs(Relation rel, const VacuumParams *params,
+ struct VacuumCutoffs *cutoffs)
{
int freeze_min_age,
multixact_freeze_min_age,
@@ -954,6 +940,10 @@ vacuum_set_xid_limits(Relation rel, const VacuumParams *params,
freeze_table_age = params->freeze_table_age;
multixact_freeze_table_age = params->multixact_freeze_table_age;
+ /* Set pg_class fields in cutoffs */
+ cutoffs->relfrozenxid = rel->rd_rel->relfrozenxid;
+ cutoffs->relminmxid = rel->rd_rel->relminmxid;
+
/*
* Acquire OldestXmin.
*
@@ -965,14 +955,14 @@ vacuum_set_xid_limits(Relation rel, const VacuumParams *params,
* that only one vacuum process can be working on a particular table at
* any time, and that each vacuum is always an independent transaction.
*/
- *OldestXmin = GetOldestNonRemovableTransactionId(rel);
+ cutoffs->OldestXmin = GetOldestNonRemovableTransactionId(rel);
if (OldSnapshotThresholdActive())
{
TransactionId limit_xmin;
TimestampTz limit_ts;
- if (TransactionIdLimitedForOldSnapshots(*OldestXmin, rel,
+ if (TransactionIdLimitedForOldSnapshots(cutoffs->OldestXmin, rel,
&limit_xmin, &limit_ts))
{
/*
@@ -982,21 +972,49 @@ vacuum_set_xid_limits(Relation rel, const VacuumParams *params,
* frequency), but would still be a significant improvement.
*/
SetOldSnapshotThresholdTimestamp(limit_ts, limit_xmin);
- *OldestXmin = limit_xmin;
+ cutoffs->OldestXmin = limit_xmin;
}
}
- Assert(TransactionIdIsNormal(*OldestXmin));
+ Assert(TransactionIdIsNormal(cutoffs->OldestXmin));
/* Acquire OldestMxact */
- *OldestMxact = GetOldestMultiXactId();
- Assert(MultiXactIdIsValid(*OldestMxact));
+ cutoffs->OldestMxact = GetOldestMultiXactId();
+ Assert(MultiXactIdIsValid(cutoffs->OldestMxact));
/* Acquire next XID/next MXID values used to apply age-based settings */
nextXID = ReadNextTransactionId();
nextMXID = ReadNextMultiXactId();
/*
+ * Also compute the multixact age for which freezing is urgent. This is
+ * normally autovacuum_multixact_freeze_max_age, but may be less if we are
+ * short of multixact member space.
+ */
+ effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();
+
+ /*
+ * Almost ready to set freeze output parameters; check if OldestXmin or
+ * OldestMxact are held back to an unsafe degree before we start on that
+ */
+ safeOldestXmin = nextXID - autovacuum_freeze_max_age;
+ if (!TransactionIdIsNormal(safeOldestXmin))
+ safeOldestXmin = FirstNormalTransactionId;
+ safeOldestMxact = nextMXID - effective_multixact_freeze_max_age;
+ if (safeOldestMxact < FirstMultiXactId)
+ safeOldestMxact = FirstMultiXactId;
+ if (TransactionIdPrecedes(cutoffs->OldestXmin, safeOldestXmin))
+ ereport(WARNING,
+ (errmsg("cutoff for removing and freezing tuples is far in the past"),
+ errhint("Close open transactions soon to avoid wraparound problems.\n"
+ "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
+ if (MultiXactIdPrecedes(cutoffs->OldestMxact, safeOldestMxact))
+ ereport(WARNING,
+ (errmsg("cutoff for freezing multixacts is far in the past"),
+ errhint("Close open transactions soon to avoid wraparound problems.\n"
+ "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
+
+ /*
* Determine the minimum freeze age to use: as specified by the caller, or
* vacuum_freeze_min_age, but in any case not more than half
* autovacuum_freeze_max_age, so that autovacuums to prevent XID
@@ -1008,19 +1026,12 @@ vacuum_set_xid_limits(Relation rel, const VacuumParams *params,
Assert(freeze_min_age >= 0);
/* Compute FreezeLimit, being careful to generate a normal XID */
- *FreezeLimit = nextXID - freeze_min_age;
- if (!TransactionIdIsNormal(*FreezeLimit))
- *FreezeLimit = FirstNormalTransactionId;
+ cutoffs->FreezeLimit = nextXID - freeze_min_age;
+ if (!TransactionIdIsNormal(cutoffs->FreezeLimit))
+ cutoffs->FreezeLimit = FirstNormalTransactionId;
/* FreezeLimit must always be <= OldestXmin */
- if (TransactionIdPrecedes(*OldestXmin, *FreezeLimit))
- *FreezeLimit = *OldestXmin;
-
- /*
- * Compute the multixact age for which freezing is urgent. This is
- * normally autovacuum_multixact_freeze_max_age, but may be less if we are
- * short of multixact member space.
- */
- effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();
+ if (TransactionIdPrecedes(cutoffs->OldestXmin, cutoffs->FreezeLimit))
+ cutoffs->FreezeLimit = cutoffs->OldestXmin;
/*
* Determine the minimum multixact freeze age to use: as specified by
@@ -1035,33 +1046,12 @@ vacuum_set_xid_limits(Relation rel, const VacuumParams *params,
Assert(multixact_freeze_min_age >= 0);
/* Compute MultiXactCutoff, being careful to generate a valid value */
- *MultiXactCutoff = nextMXID - multixact_freeze_min_age;
- if (*MultiXactCutoff < FirstMultiXactId)
- *MultiXactCutoff = FirstMultiXactId;
+ cutoffs->MultiXactCutoff = nextMXID - multixact_freeze_min_age;
+ if (cutoffs->MultiXactCutoff < FirstMultiXactId)
+ cutoffs->MultiXactCutoff = FirstMultiXactId;
/* MultiXactCutoff must always be <= OldestMxact */
- if (MultiXactIdPrecedes(*OldestMxact, *MultiXactCutoff))
- *MultiXactCutoff = *OldestMxact;
-
- /*
- * Done setting output parameters; check if OldestXmin or OldestMxact are
- * held back to an unsafe degree in passing
- */
- safeOldestXmin = nextXID - autovacuum_freeze_max_age;
- if (!TransactionIdIsNormal(safeOldestXmin))
- safeOldestXmin = FirstNormalTransactionId;
- safeOldestMxact = nextMXID - effective_multixact_freeze_max_age;
- if (safeOldestMxact < FirstMultiXactId)
- safeOldestMxact = FirstMultiXactId;
- if (TransactionIdPrecedes(*OldestXmin, safeOldestXmin))
- ereport(WARNING,
- (errmsg("cutoff for removing and freezing tuples is far in the past"),
- errhint("Close open transactions soon to avoid wraparound problems.\n"
- "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
- if (MultiXactIdPrecedes(*OldestMxact, safeOldestMxact))
- ereport(WARNING,
- (errmsg("cutoff for freezing multixacts is far in the past"),
- errhint("Close open transactions soon to avoid wraparound problems.\n"
- "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
+ if (MultiXactIdPrecedes(cutoffs->OldestMxact, cutoffs->MultiXactCutoff))
+ cutoffs->MultiXactCutoff = cutoffs->OldestMxact;
/*
* Finally, figure out if caller needs to do an aggressive VACUUM or not.
@@ -1113,13 +1103,13 @@ vacuum_set_xid_limits(Relation rel, const VacuumParams *params,
* mechanism to determine if its table's relfrozenxid and relminmxid are now
* dangerously far in the past.
*
- * Input parameters are the target relation's relfrozenxid and relminmxid.
- *
* When we return true, VACUUM caller triggers the failsafe.
*/
bool
-vacuum_xid_failsafe_check(TransactionId relfrozenxid, MultiXactId relminmxid)
+vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs)
{
+ TransactionId relfrozenxid = cutoffs->relfrozenxid;
+ MultiXactId relminmxid = cutoffs->relminmxid;
TransactionId xid_skip_limit;
MultiXactId multi_skip_limit;
int skip_index_vacuum;