aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Geoghegan <pg@bowt.ie>2022-02-11 18:26:15 -0800
committerPeter Geoghegan <pg@bowt.ie>2022-02-11 18:26:15 -0800
commitefa4a9462a072b4cd6459058df274dd23022d0e2 (patch)
tree8adfe9b4a3e94e7d2f7bab72d775952880e784d4 /src
parent872770fd6ccf12596b9e26234df9a37cae083af2 (diff)
downloadpostgresql-efa4a9462a072b4cd6459058df274dd23022d0e2.tar.gz
postgresql-efa4a9462a072b4cd6459058df274dd23022d0e2.zip
Consolidate VACUUM xid cutoff logic.
Push the logic for determining whether or not a VACUUM operation will be aggressive down into vacuum_set_xid_limits(). This makes the function's signature significantly simpler, and seems clearer overall. Author: Peter Geoghegan <pg@bowt.ie> Discussion: https://postgr.es/m/CAH2-WzkymFbz6D_vL+jmqSn_5q1wsFvFrE+37yLgL_Rkfd6Gzg@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/heap/vacuumlazy.c34
-rw-r--r--src/backend/commands/cluster.c3
-rw-r--r--src/backend/commands/vacuum.c131
-rw-r--r--src/include/commands/vacuum.h6
4 files changed, 79 insertions, 95 deletions
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index fed25f49294..d57055674ed 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -323,8 +323,6 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
minmulti_updated;
BlockNumber orig_rel_pages;
char **indnames = NULL;
- TransactionId xidFullScanLimit;
- MultiXactId mxactFullScanLimit;
BlockNumber new_rel_pages;
BlockNumber new_rel_allvisible;
double new_live_tuples;
@@ -352,24 +350,24 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM,
RelationGetRelid(rel));
- vacuum_set_xid_limits(rel,
- params->freeze_min_age,
- params->freeze_table_age,
- params->multixact_freeze_min_age,
- params->multixact_freeze_table_age,
- &OldestXmin, &FreezeLimit, &xidFullScanLimit,
- &MultiXactCutoff, &mxactFullScanLimit);
-
/*
- * We request an aggressive scan if the table's frozen Xid is now older
- * than or equal to the requested Xid full-table scan limit; or if the
- * table's minimum MultiXactId is older than or equal to the requested
- * mxid full-table scan limit; or if DISABLE_PAGE_SKIPPING was specified.
+ * Get OldestXmin cutoff, which is used to determine which deleted tuples
+ * are considered DEAD, not just RECENTLY_DEAD. Also get related cutoffs
+ * used to determine which XIDs/MultiXactIds will be frozen.
+ *
+ * If this is an aggressive VACUUM, then we're strictly required to freeze
+ * any and all XIDs from before FreezeLimit, so that we will be able to
+ * safely advance relfrozenxid up to FreezeLimit below (we must be able to
+ * advance relminmxid up to MultiXactCutoff, too).
*/
- aggressive = TransactionIdPrecedesOrEquals(rel->rd_rel->relfrozenxid,
- xidFullScanLimit);
- aggressive |= MultiXactIdPrecedesOrEquals(rel->rd_rel->relminmxid,
- mxactFullScanLimit);
+ aggressive = vacuum_set_xid_limits(rel,
+ params->freeze_min_age,
+ params->freeze_table_age,
+ params->multixact_freeze_min_age,
+ params->multixact_freeze_table_age,
+ &OldestXmin, &FreezeLimit,
+ &MultiXactCutoff);
+
skipwithvm = true;
if (params->options & VACOPT_DISABLE_PAGE_SKIPPING)
{
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 2e8efe4f8fc..02a7e94bf9b 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -857,8 +857,7 @@ copy_table_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
* not to be aggressive about this.
*/
vacuum_set_xid_limits(OldHeap, 0, 0, 0, 0,
- &OldestXmin, &FreezeXid, NULL, &MultiXactCutoff,
- NULL);
+ &OldestXmin, &FreezeXid, &MultiXactCutoff);
/*
* FreezeXid will become the table's new relfrozenxid, and that mustn't go
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 37413dd43e9..b6767a5ff8c 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -943,24 +943,18 @@ get_all_vacuum_rels(int options)
* Input parameters are the target relation, applicable freeze age settings.
*
* The output parameters are:
- * - oldestXmin is the cutoff value used to distinguish whether tuples are
- * DEAD or RECENTLY_DEAD (see HeapTupleSatisfiesVacuum).
+ * - oldestXmin is the Xid below which tuples deleted by any xact (that
+ * committed) should be considered DEAD, not just RECENTLY_DEAD.
* - freezeLimit is the Xid below which all Xids are replaced by
* FrozenTransactionId during vacuum.
- * - xidFullScanLimit (computed from freeze_table_age parameter)
- * represents a minimum Xid value; a table whose relfrozenxid is older than
- * this will have a full-table vacuum applied to it, to freeze tuples across
- * the whole table. Vacuuming a table younger than this value can use a
- * partial scan.
- * - multiXactCutoff is the value below which all MultiXactIds are removed from
- * Xmax.
- * - mxactFullScanLimit is a value against which a table's relminmxid value is
- * compared to produce a full-table vacuum, as with xidFullScanLimit.
+ * - multiXactCutoff is the value below which all MultiXactIds are removed
+ * from Xmax.
*
- * xidFullScanLimit and mxactFullScanLimit can be passed as NULL if caller is
- * not interested.
+ * Return value indicates if vacuumlazy.c caller should make its VACUUM
+ * operation aggressive. An aggressive VACUUM must advance relfrozenxid up to
+ * FreezeLimit, and relminmxid up to multiXactCutoff.
*/
-void
+bool
vacuum_set_xid_limits(Relation rel,
int freeze_min_age,
int freeze_table_age,
@@ -968,9 +962,7 @@ vacuum_set_xid_limits(Relation rel,
int multixact_freeze_table_age,
TransactionId *oldestXmin,
TransactionId *freezeLimit,
- TransactionId *xidFullScanLimit,
- MultiXactId *multiXactCutoff,
- MultiXactId *mxactFullScanLimit)
+ MultiXactId *multiXactCutoff)
{
int freezemin;
int mxid_freezemin;
@@ -980,6 +972,7 @@ vacuum_set_xid_limits(Relation rel,
MultiXactId oldestMxact;
MultiXactId mxactLimit;
MultiXactId safeMxactLimit;
+ int freezetable;
/*
* We can always ignore processes running lazy vacuum. This is because we
@@ -1097,64 +1090,60 @@ vacuum_set_xid_limits(Relation rel,
*multiXactCutoff = mxactLimit;
- if (xidFullScanLimit != NULL)
- {
- int freezetable;
-
- Assert(mxactFullScanLimit != NULL);
-
- /*
- * Determine the table freeze age to use: as specified by the caller,
- * or vacuum_freeze_table_age, but in any case not more than
- * autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
- * VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples
- * before anti-wraparound autovacuum is launched.
- */
- freezetable = freeze_table_age;
- if (freezetable < 0)
- freezetable = vacuum_freeze_table_age;
- freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95);
- Assert(freezetable >= 0);
-
- /*
- * Compute XID limit causing a full-table vacuum, being careful not to
- * generate a "permanent" XID.
- */
- limit = ReadNextTransactionId() - freezetable;
- if (!TransactionIdIsNormal(limit))
- limit = FirstNormalTransactionId;
+ /*
+ * Done setting output parameters; just need to figure out if caller needs
+ * to do an aggressive VACUUM or not.
+ *
+ * Determine the table freeze age to use: as specified by the caller, or
+ * vacuum_freeze_table_age, but in any case not more than
+ * autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
+ * VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples
+ * before anti-wraparound autovacuum is launched.
+ */
+ freezetable = freeze_table_age;
+ if (freezetable < 0)
+ freezetable = vacuum_freeze_table_age;
+ freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95);
+ Assert(freezetable >= 0);
- *xidFullScanLimit = limit;
+ /*
+ * Compute XID limit causing an aggressive vacuum, being careful not to
+ * generate a "permanent" XID
+ */
+ limit = ReadNextTransactionId() - freezetable;
+ if (!TransactionIdIsNormal(limit))
+ limit = FirstNormalTransactionId;
+ if (TransactionIdPrecedesOrEquals(rel->rd_rel->relfrozenxid,
+ limit))
+ return true;
- /*
- * Similar to the above, determine the table freeze age to use for
- * multixacts: as specified by the caller, or
- * vacuum_multixact_freeze_table_age, but in any case not more than
- * autovacuum_multixact_freeze_table_age * 0.95, so that if you have
- * e.g. nightly VACUUM schedule, the nightly VACUUM gets a chance to
- * freeze multixacts before anti-wraparound autovacuum is launched.
- */
- freezetable = multixact_freeze_table_age;
- if (freezetable < 0)
- freezetable = vacuum_multixact_freeze_table_age;
- freezetable = Min(freezetable,
- effective_multixact_freeze_max_age * 0.95);
- Assert(freezetable >= 0);
+ /*
+ * Similar to the above, determine the table freeze age to use for
+ * multixacts: as specified by the caller, or
+ * vacuum_multixact_freeze_table_age, but in any case not more than
+ * autovacuum_multixact_freeze_table_age * 0.95, so that if you have e.g.
+ * nightly VACUUM schedule, the nightly VACUUM gets a chance to freeze
+ * multixacts before anti-wraparound autovacuum is launched.
+ */
+ freezetable = multixact_freeze_table_age;
+ if (freezetable < 0)
+ freezetable = vacuum_multixact_freeze_table_age;
+ freezetable = Min(freezetable,
+ effective_multixact_freeze_max_age * 0.95);
+ Assert(freezetable >= 0);
- /*
- * Compute MultiXact limit causing a full-table vacuum, being careful
- * to generate a valid MultiXact value.
- */
- mxactLimit = ReadNextMultiXactId() - freezetable;
- if (mxactLimit < FirstMultiXactId)
- mxactLimit = FirstMultiXactId;
+ /*
+ * Compute MultiXact limit causing an aggressive vacuum, being careful to
+ * generate a valid MultiXact value
+ */
+ mxactLimit = ReadNextMultiXactId() - freezetable;
+ if (mxactLimit < FirstMultiXactId)
+ mxactLimit = FirstMultiXactId;
+ if (MultiXactIdPrecedesOrEquals(rel->rd_rel->relminmxid,
+ mxactLimit))
+ return true;
- *mxactFullScanLimit = mxactLimit;
- }
- else
- {
- Assert(mxactFullScanLimit == NULL);
- }
+ return false;
}
/*
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index e5e548d6b9a..d64f6268f23 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -286,15 +286,13 @@ extern void vac_update_relstats(Relation relation,
bool *frozenxid_updated,
bool *minmulti_updated,
bool in_outer_xact);
-extern void vacuum_set_xid_limits(Relation rel,
+extern bool vacuum_set_xid_limits(Relation rel,
int freeze_min_age, int freeze_table_age,
int multixact_freeze_min_age,
int multixact_freeze_table_age,
TransactionId *oldestXmin,
TransactionId *freezeLimit,
- TransactionId *xidFullScanLimit,
- MultiXactId *multiXactCutoff,
- MultiXactId *mxactFullScanLimit);
+ MultiXactId *multiXactCutoff);
extern bool vacuum_xid_failsafe_check(TransactionId relfrozenxid,
MultiXactId relminmxid);
extern void vac_update_datfrozenxid(void);