diff options
author | Peter Geoghegan <pg@bowt.ie> | 2022-12-22 09:37:59 -0800 |
---|---|---|
committer | Peter Geoghegan <pg@bowt.ie> | 2022-12-22 09:37:59 -0800 |
commit | 4ce3afb82ecfbf64d4f6247e725004e1da30f47c (patch) | |
tree | bee5ce2942c24110262039543dca87b66ff6a914 /src/include | |
parent | e42e312430279dcd8947846fdfeb4885e3754eac (diff) | |
download | postgresql-4ce3afb82ecfbf64d4f6247e725004e1da30f47c.tar.gz postgresql-4ce3afb82ecfbf64d4f6247e725004e1da30f47c.zip |
Refactor how VACUUM passes around its XID cutoffs.
Use a dedicated struct for the XID/MXID cutoffs used by VACUUM, such as
FreezeLimit and OldestXmin. This state is initialized in vacuum.c, and
then passed around by code from vacuumlazy.c to heapam.c freezing
related routines. The new convention is that everybody works off of the
same cutoff state, which is passed around via pointers to const.
Also simplify some of the logic for dealing with frozen xmin in
heap_prepare_freeze_tuple: add dedicated "xmin_already_frozen" state to
clearly distinguish xmin XIDs that we're going to freeze from those that
were already frozen from before. That way the routine's xmin handling
code is symmetrical with the existing xmax handling code. This is
preparation for an upcoming commit that will add page level freezing.
Also refactor the control flow within FreezeMultiXactId(), while adding
stricter sanity checks. We now test OldestXmin directly, instead of
using FreezeLimit as an inexact proxy for OldestXmin. This is further
preparation for the page level freezing work, which will make the
function's caller cede control of page level freezing to the function
where appropriate (where heap_prepare_freeze_tuple sees a tuple that
happens to contain a MultiXactId in its xmax).
Author: Peter Geoghegan <pg@bowt.ie>
Reviewed-By: Jeff Davis <pgsql@j-davis.com>
Discussion: https://postgr.es/m/CAH2-WznS9TxXmz2_=SY+SyJyDFbiOftKofM9=aDo68BbXNBUMA@mail.gmail.com
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/access/heapam.h | 10 | ||||
-rw-r--r-- | src/include/access/tableam.h | 2 | ||||
-rw-r--r-- | src/include/commands/vacuum.h | 49 |
3 files changed, 48 insertions, 13 deletions
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 810baaf9d08..53eb011766b 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -38,6 +38,7 @@ typedef struct BulkInsertStateData *BulkInsertState; struct TupleTableSlot; +struct VacuumCutoffs; #define MaxLockTupleMode LockTupleExclusive @@ -178,8 +179,7 @@ extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, extern void heap_inplace_update(Relation relation, HeapTuple tuple); extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple, - TransactionId relfrozenxid, TransactionId relminmxid, - TransactionId cutoff_xid, TransactionId cutoff_multi, + const struct VacuumCutoffs *cutoffs, HeapTupleFreeze *frz, bool *totally_frozen, TransactionId *relfrozenxid_out, MultiXactId *relminmxid_out); @@ -188,9 +188,9 @@ extern void heap_freeze_execute_prepared(Relation rel, Buffer buffer, HeapTupleFreeze *tuples, int ntuples); extern bool heap_freeze_tuple(HeapTupleHeader tuple, TransactionId relfrozenxid, TransactionId relminmxid, - TransactionId cutoff_xid, TransactionId cutoff_multi); -extern bool heap_tuple_would_freeze(HeapTupleHeader tuple, TransactionId cutoff_xid, - MultiXactId cutoff_multi, + TransactionId FreezeLimit, TransactionId MultiXactCutoff); +extern bool heap_tuple_would_freeze(HeapTupleHeader tuple, + const struct VacuumCutoffs *cutoffs, TransactionId *relfrozenxid_out, MultiXactId *relminmxid_out); extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple); diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 4d1ef405c22..1320ee6db66 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -1634,7 +1634,7 @@ table_relation_copy_data(Relation rel, const RelFileLocator *newrlocator) * in that index's order; if false and OldIndex is InvalidOid, no sorting is * performed * - OldIndex - see use_sort - * - OldestXmin - computed by vacuum_set_xid_limits(), even when + * - OldestXmin - computed by vacuum_get_cutoffs(), even when * not needed for the relation's AM * - *xid_cutoff - ditto * - *multi_cutoff - ditto diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 4e4bc26a8bf..2f274f2bec3 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -236,6 +236,45 @@ typedef struct VacuumParams } VacuumParams; /* + * VacuumCutoffs is immutable state that describes the cutoffs used by VACUUM. + * Established at the beginning of each VACUUM operation. + */ +struct VacuumCutoffs +{ + /* + * Existing pg_class fields at start of VACUUM + */ + TransactionId relfrozenxid; + MultiXactId relminmxid; + + /* + * 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. + * + * OldestXmin and OldestMxact are also the most recent values that can + * ever be passed to vac_update_relstats() as frozenxid and minmulti + * arguments at the end of VACUUM. These same values should be passed + * when it turns out that VACUUM will leave no unfrozen XIDs/MXIDs behind + * in the table. + */ + TransactionId OldestXmin; + MultiXactId OldestMxact; + + /* + * FreezeLimit is the Xid below which all Xids are definitely frozen or + * removed in pages VACUUM scans and cleanup locks. + * + * MultiXactCutoff is the value below which all MultiXactIds are + * definitely removed from Xmax in pages VACUUM scans and cleanup locks. + */ + TransactionId FreezeLimit; + MultiXactId MultiXactCutoff; +}; + +/* * VacDeadItems stores TIDs whose index tuples are deleted by index vacuuming. */ typedef struct VacDeadItems @@ -286,13 +325,9 @@ extern void vac_update_relstats(Relation relation, bool *frozenxid_updated, bool *minmulti_updated, bool in_outer_xact); -extern bool vacuum_set_xid_limits(Relation rel, const VacuumParams *params, - TransactionId *OldestXmin, - MultiXactId *OldestMxact, - TransactionId *FreezeLimit, - MultiXactId *MultiXactCutoff); -extern bool vacuum_xid_failsafe_check(TransactionId relfrozenxid, - MultiXactId relminmxid); +extern bool vacuum_get_cutoffs(Relation rel, const VacuumParams *params, + struct VacuumCutoffs *cutoffs); +extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(void); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, |