/*
* Scan pg_database to compute the minimum datfrozenxid/datminmxid
*
+ * Since vac_update_datfrozenxid updates datfrozenxid/datminmxid in-place,
+ * the values could change while we look at them. Fetch each one just
+ * once to ensure sane behavior of the comparison logic. (Here, as in
+ * many other places, we assume that fetching or updating an XID in shared
+ * storage is atomic.)
+ *
* Note: we need not worry about a race condition with new entries being
* inserted by CREATE DATABASE. Any such entry will have a copy of some
* existing DB's datfrozenxid, and that source DB cannot be ours because
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
- Form_pg_database dbform = (Form_pg_database) GETSTRUCT(tuple);
+ volatile FormData_pg_database *dbform = (Form_pg_database) GETSTRUCT(tuple);
+ TransactionId datfrozenxid = dbform->datfrozenxid;
+ TransactionId datminmxid = dbform->datminmxid;
- Assert(TransactionIdIsNormal(dbform->datfrozenxid));
- Assert(MultiXactIdIsValid(dbform->datminmxid));
+ Assert(TransactionIdIsNormal(datfrozenxid));
+ Assert(MultiXactIdIsValid(datminmxid));
/*
* If things are working properly, no database should have a
* databases have been scanned and cleaned up. (We will issue the
* "already wrapped" warning if appropriate, though.)
*/
- if (TransactionIdPrecedes(lastSaneFrozenXid, dbform->datfrozenxid) ||
- MultiXactIdPrecedes(lastSaneMinMulti, dbform->datminmxid))
+ if (TransactionIdPrecedes(lastSaneFrozenXid, datfrozenxid) ||
+ MultiXactIdPrecedes(lastSaneMinMulti, datminmxid))
bogus = true;
- if (TransactionIdPrecedes(nextXID, dbform->datfrozenxid))
+ if (TransactionIdPrecedes(nextXID, datfrozenxid))
frozenAlreadyWrapped = true;
- else if (TransactionIdPrecedes(dbform->datfrozenxid, frozenXID))
+ else if (TransactionIdPrecedes(datfrozenxid, frozenXID))
{
- frozenXID = dbform->datfrozenxid;
+ frozenXID = datfrozenxid;
oldestxid_datoid = HeapTupleGetOid(tuple);
}
- if (MultiXactIdPrecedes(dbform->datminmxid, minMulti))
+ if (MultiXactIdPrecedes(datminmxid, minMulti))
{
- minMulti = dbform->datminmxid;
+ minMulti = datminmxid;
minmulti_datoid = HeapTupleGetOid(tuple);
}
}