/*
* Note that this code handles IS_MULTI Xmax values, too, but only to mark
- * the tuple frozen if the updating Xid in the mxact is below the freeze
- * cutoff; it doesn't remove dead members of a very old multixact.
+ * the tuple as not updated if the multixact is below the cutoff Multixact
+ * given; it doesn't remove dead members of a very old multixact.
*/
xid = HeapTupleHeaderGetRawXmax(tuple);
if ((tuple->t_infomask & HEAP_XMAX_IS_MULTI) ?
* determine tuple visibility */
TransactionId rs_freeze_xid;/* Xid that will be used as freeze cutoff
* point */
- MultiXactId rs_freeze_multi;/* MultiXactId that will be used as freeze
- * cutoff point for multixacts */
+ MultiXactId rs_cutoff_multi;/* MultiXactId that will be used as cutoff
+ * point for multixacts */
MemoryContext rs_cxt; /* for hash tables and entries and tuples in
* them */
HTAB *rs_unresolved_tups; /* unmatched A tuples */
* new_heap new, locked heap relation to insert tuples to
* oldest_xmin xid used by the caller to determine which tuples are dead
* freeze_xid xid before which tuples will be frozen
- * freeze_multi multixact before which multis will be frozen
+ * min_multi multixact before which multis will be removed
* use_wal should the inserts to the new heap be WAL-logged?
*
* Returns an opaque RewriteState, allocated in current memory context,
*/
RewriteState
begin_heap_rewrite(Relation new_heap, TransactionId oldest_xmin,
- TransactionId freeze_xid, MultiXactId freeze_multi,
+ TransactionId freeze_xid, MultiXactId cutoff_multi,
bool use_wal)
{
RewriteState state;
state->rs_use_wal = use_wal;
state->rs_oldest_xmin = oldest_xmin;
state->rs_freeze_xid = freeze_xid;
- state->rs_freeze_multi = freeze_multi;
+ state->rs_cutoff_multi = cutoff_multi;
state->rs_cxt = rw_cxt;
/* Initialize hash tables used to track update chains */
* very-old xmin or xmax, so that future VACUUM effort can be saved.
*/
heap_freeze_tuple(new_tuple->t_data, state->rs_freeze_xid,
- state->rs_freeze_multi);
+ state->rs_cutoff_multi);
/*
* Invalid ctid means that ctid should point to the tuple itself. We'll
* We check known limits on MultiXact before resorting to the SLRU area.
*
* An ID older than MultiXactState->oldestMultiXactId cannot possibly be
- * useful; it should have already been frozen by vacuum. We've truncated
+ * useful; it should have already been removed by vacuum. We've truncated
* the on-disk structures anyway. Returning the wrong values could lead
* to an incorrect visibility result. However, to support pg_upgrade we
* need to allow an empty set to be returned regardless, if the caller is
static void copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
int freeze_min_age, int freeze_table_age, bool verbose,
bool *pSwapToastByContent, TransactionId *pFreezeXid,
- MultiXactId *pFreezeMulti);
+ MultiXactId *pCutoffMulti);
static List *get_tables_to_cluster(MemoryContext cluster_context);
static void reform_and_rewrite_tuple(HeapTuple tuple,
TupleDesc oldTupDesc, TupleDesc newTupDesc,
bool is_system_catalog;
bool swap_toast_by_content;
TransactionId frozenXid;
- MultiXactId frozenMulti;
+ MultiXactId cutoffMulti;
/* Mark the correct index as clustered */
if (OidIsValid(indexOid))
/* Copy the heap data into the new table in the desired order */
copy_heap_data(OIDNewHeap, tableOid, indexOid,
freeze_min_age, freeze_table_age, verbose,
- &swap_toast_by_content, &frozenXid, &frozenMulti);
+ &swap_toast_by_content, &frozenXid, &cutoffMulti);
/*
* Swap the physical files of the target and transient tables, then
*/
finish_heap_swap(tableOid, OIDNewHeap, is_system_catalog,
swap_toast_by_content, false, true,
- frozenXid, frozenMulti);
+ frozenXid, cutoffMulti);
}
* There are two output parameters:
* *pSwapToastByContent is set true if toast tables must be swapped by content.
* *pFreezeXid receives the TransactionId used as freeze cutoff point.
+ * *pCutoffMulti receives the MultiXactId used as a cutoff point.
*/
static void
copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
int freeze_min_age, int freeze_table_age, bool verbose,
bool *pSwapToastByContent, TransactionId *pFreezeXid,
- MultiXactId *pFreezeMulti)
+ MultiXactId *pCutoffMulti)
{
Relation NewHeap,
OldHeap,
bool is_system_catalog;
TransactionId OldestXmin;
TransactionId FreezeXid;
- MultiXactId MultiXactFrzLimit;
+ MultiXactId MultiXactCutoff;
RewriteState rwstate;
bool use_sort;
Tuplesortstate *tuplesort;
*/
vacuum_set_xid_limits(freeze_min_age, freeze_table_age,
OldHeap->rd_rel->relisshared,
- &OldestXmin, &FreezeXid, NULL, &MultiXactFrzLimit);
+ &OldestXmin, &FreezeXid, NULL, &MultiXactCutoff);
/*
* FreezeXid will become the table's new relfrozenxid, and that mustn't go
/* return selected values to caller */
*pFreezeXid = FreezeXid;
- *pFreezeMulti = MultiXactFrzLimit;
+ *pCutoffMulti = MultiXactCutoff;
/* Remember if it's a system catalog */
is_system_catalog = IsSystemRelation(OldHeap);
/* Initialize the rewrite operation */
rwstate = begin_heap_rewrite(NewHeap, OldestXmin, FreezeXid,
- MultiXactFrzLimit, use_wal);
+ MultiXactCutoff, use_wal);
/*
* Decide whether to use an indexscan or seqscan-and-optional-sort to scan
bool swap_toast_by_content,
bool is_internal,
TransactionId frozenXid,
- MultiXactId frozenMulti,
+ MultiXactId cutoffMulti,
Oid *mapped_tables)
{
Relation relRelation;
{
Assert(TransactionIdIsNormal(frozenXid));
relform1->relfrozenxid = frozenXid;
- Assert(MultiXactIdIsValid(frozenMulti));
- relform1->relminmxid = frozenMulti;
+ Assert(MultiXactIdIsValid(cutoffMulti));
+ relform1->relminmxid = cutoffMulti;
}
/* swap size statistics too, since new rel has freshly-updated stats */
swap_toast_by_content,
is_internal,
frozenXid,
- frozenMulti,
+ cutoffMulti,
mapped_tables);
}
else
bool check_constraints,
bool is_internal,
TransactionId frozenXid,
- MultiXactId frozenMulti)
+ MultiXactId cutoffMulti)
{
ObjectAddress object;
Oid mapped_tables[4];
swap_relation_files(OIDOldHeap, OIDNewHeap,
(OIDOldHeap == RelationRelationId),
swap_toast_by_content, is_internal,
- frozenXid, frozenMulti, mapped_tables);
+ frozenXid, cutoffMulti, mapped_tables);
/*
* If it's a system catalog, queue an sinval message to flush all
/* limit of frozen XIDs */
if (dbFrozenXidP)
*dbFrozenXidP = dbform->datfrozenxid;
- /* limit of frozen Multixacts */
+ /* minimum MultixactId */
if (dbMinMultiP)
*dbMinMultiP = dbform->datminmxid;
/* default tablespace for this database */
/* non-export function prototypes */
static List *get_rel_oids(Oid relid, const RangeVar *vacrel);
-static void vac_truncate_clog(TransactionId frozenXID, MultiXactId frozenMulti);
+static void vac_truncate_clog(TransactionId frozenXID, MultiXactId minMulti);
static bool vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast,
bool for_wraparound);
TransactionId *oldestXmin,
TransactionId *freezeLimit,
TransactionId *freezeTableLimit,
- MultiXactId *multiXactFrzLimit)
+ MultiXactId *multiXactCutoff)
{
int freezemin;
TransactionId limit;
*freezeTableLimit = limit;
}
- if (multiXactFrzLimit != NULL)
+ if (multiXactCutoff != NULL)
{
MultiXactId mxLimit;
if (mxLimit < FirstMultiXactId)
mxLimit = FirstMultiXactId;
- *multiXactFrzLimit = mxLimit;
+ *multiXactCutoff = mxLimit;
}
}
* Update pg_database's datfrozenxid entry for our database to be the
* minimum of the pg_class.relfrozenxid values.
*
- * Similarly, update our datfrozenmulti to be the minimum of the
- * pg_class.relfrozenmulti values.
+ * Similarly, update our datminmxid to be the minimum of the
+ * pg_class.relminmxid values.
*
* If we are able to advance either pg_database value, also try to
* truncate pg_clog and pg_multixact.
SysScanDesc scan;
HeapTuple classTup;
TransactionId newFrozenXid;
- MultiXactId newFrozenMulti;
+ MultiXactId newMinMulti;
bool dirty = false;
/*
* Similarly, initialize the MultiXact "min" with the value that would be
* used on pg_class for new tables. See AddNewRelationTuple().
*/
- newFrozenMulti = GetOldestMultiXactId();
+ newMinMulti = GetOldestMultiXactId();
/*
* We must seqscan pg_class to find the minimum Xid, because there is no
if (TransactionIdPrecedes(classForm->relfrozenxid, newFrozenXid))
newFrozenXid = classForm->relfrozenxid;
- if (MultiXactIdPrecedes(classForm->relminmxid, newFrozenMulti))
- newFrozenMulti = classForm->relminmxid;
+ if (MultiXactIdPrecedes(classForm->relminmxid, newMinMulti))
+ newMinMulti = classForm->relminmxid;
}
/* we're done with pg_class */
heap_close(relation, AccessShareLock);
Assert(TransactionIdIsNormal(newFrozenXid));
- Assert(MultiXactIdIsValid(newFrozenMulti));
+ Assert(MultiXactIdIsValid(newMinMulti));
/* Now fetch the pg_database tuple we need to update. */
relation = heap_open(DatabaseRelationId, RowExclusiveLock);
}
/* ditto */
- if (MultiXactIdPrecedes(dbform->datminmxid, newFrozenMulti))
+ if (MultiXactIdPrecedes(dbform->datminmxid, newMinMulti))
{
- dbform->datminmxid = newFrozenMulti;
+ dbform->datminmxid = newMinMulti;
dirty = true;
}
* this action will update that too.
*/
if (dirty || ForceTransactionIdLimitUpdate())
- vac_truncate_clog(newFrozenXid, newFrozenMulti);
+ vac_truncate_clog(newFrozenXid, newMinMulti);
}
* info is stale.
*/
static void
-vac_truncate_clog(TransactionId frozenXID, MultiXactId frozenMulti)
+vac_truncate_clog(TransactionId frozenXID, MultiXactId minMulti)
{
TransactionId myXID = GetCurrentTransactionId();
Relation relation;
HeapScanDesc scan;
HeapTuple tuple;
Oid oldestxid_datoid;
- Oid oldestmulti_datoid;
+ Oid minmulti_datoid;
bool frozenAlreadyWrapped = false;
/* init oldest datoids to sync with my frozen values */
oldestxid_datoid = MyDatabaseId;
- oldestmulti_datoid = MyDatabaseId;
+ minmulti_datoid = MyDatabaseId;
/*
* Scan pg_database to compute the minimum datfrozenxid
oldestxid_datoid = HeapTupleGetOid(tuple);
}
- if (MultiXactIdPrecedes(dbform->datminmxid, frozenMulti))
+ if (MultiXactIdPrecedes(dbform->datminmxid, minMulti))
{
- frozenMulti = dbform->datminmxid;
- oldestmulti_datoid = HeapTupleGetOid(tuple);
+ minMulti = dbform->datminmxid;
+ minmulti_datoid = HeapTupleGetOid(tuple);
}
}
/* Truncate CLOG and Multi to the oldest computed value */
TruncateCLOG(frozenXID);
- TruncateMultiXact(frozenMulti);
+ TruncateMultiXact(minMulti);
/*
* Update the wrap limit for GetNewTransactionId and creation of new
* signalling twice?
*/
SetTransactionIdLimit(frozenXID, oldestxid_datoid);
- MultiXactAdvanceOldest(frozenMulti, oldestmulti_datoid);
+ MultiXactAdvanceOldest(minMulti, minmulti_datoid);
}
static TransactionId OldestXmin;
static TransactionId FreezeLimit;
-static MultiXactId MultiXactFrzLimit;
+static MultiXactId MultiXactCutoff;
static BufferAccessStrategy vac_strategy;
vacuum_set_xid_limits(vacstmt->freeze_min_age, vacstmt->freeze_table_age,
onerel->rd_rel->relisshared,
&OldestXmin, &FreezeLimit, &freezeTableLimit,
- &MultiXactFrzLimit);
+ &MultiXactCutoff);
scan_all = TransactionIdPrecedesOrEquals(onerel->rd_rel->relfrozenxid,
freezeTableLimit);
if (vacrelstats->scanned_pages < vacrelstats->rel_pages)
new_frozen_xid = InvalidTransactionId;
- new_min_multi = MultiXactFrzLimit;
+ new_min_multi = MultiXactCutoff;
if (vacrelstats->scanned_pages < vacrelstats->rel_pages)
new_min_multi = InvalidMultiXactId;
* freezing. Note we already have exclusive buffer lock.
*/
if (heap_freeze_tuple(tuple.t_data, FreezeLimit,
- MultiXactFrzLimit))
+ MultiXactCutoff))
frozen[nfrozen++] = offnum;
}
} /* scan along page */
XLogRecPtr recptr;
recptr = log_heap_freeze(onerel, buf, FreezeLimit,
- MultiXactFrzLimit, frozen, nfrozen);
+ MultiXactCutoff, frozen, nfrozen);
PageSetLSN(page, recptr);
}
}
tupleheader = (HeapTupleHeader) PageGetItem(page, itemid);
if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
- MultiXactFrzLimit, buf))
+ MultiXactCutoff, buf))
return true;
} /* scan along page */
Oid adw_datid;
char *adw_name;
TransactionId adw_frozenxid;
- MultiXactId adw_frozenmulti;
+ MultiXactId adw_minmulti;
PgStat_StatDBEntry *adw_entry;
} avw_dbase;
}
else if (for_xid_wrap)
continue; /* ignore not-at-risk DBs */
- else if (MultiXactIdPrecedes(tmp->adw_frozenmulti, multiForceLimit))
+ else if (MultiXactIdPrecedes(tmp->adw_minmulti, multiForceLimit))
{
if (avdb == NULL ||
- MultiXactIdPrecedes(tmp->adw_frozenmulti,
- avdb->adw_frozenmulti))
+ MultiXactIdPrecedes(tmp->adw_minmulti, avdb->adw_minmulti))
avdb = tmp;
for_multi_wrap = true;
continue;
avdb->adw_datid = HeapTupleGetOid(tup);
avdb->adw_name = pstrdup(NameStr(pgdatabase->datname));
avdb->adw_frozenxid = pgdatabase->datfrozenxid;
- avdb->adw_frozenmulti = pgdatabase->datminmxid;
+ avdb->adw_minmulti = pgdatabase->datminmxid;
/* this gets set later: */
avdb->adw_entry = NULL;
extern RewriteState begin_heap_rewrite(Relation NewHeap,
TransactionId OldestXmin, TransactionId FreezeXid,
- MultiXactId MultiXactFrzLimit, bool use_wal);
+ MultiXactId MultiXactCutoff, bool use_wal);
extern void end_heap_rewrite(RewriteState state);
extern void rewrite_heap_tuple(RewriteState state, HeapTuple oldTuple,
HeapTuple newTuple);
bool check_constraints,
bool is_internal,
TransactionId frozenXid,
- MultiXactId frozenMulti);
+ MultiXactId minMulti);
#endif /* CLUSTER_H */
TransactionId *oldestXmin,
TransactionId *freezeLimit,
TransactionId *freezeTableLimit,
- MultiXactId *multiXactFrzLimit);
+ MultiXactId *multiXactCutoff);
extern void vac_update_datfrozenxid(void);
extern void vacuum_delay_point(void);