* are older than the specified cutoff XID and cutoff MultiXactId. If so,
* setup enough state (in the *frz output argument) to later execute and
* WAL-log what we would need to do, and return TRUE. Return FALSE if nothing
- * is to be changed.
+ * is to be changed. In addition, set *totally_frozen_p to true if the tuple
+ * will be totally frozen after these operations are performed and false if
+ * more freezing will eventually be required.
*
* Caller is responsible for setting the offset field, if appropriate.
*
bool
heap_prepare_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
TransactionId cutoff_multi,
- xl_heap_freeze_tuple *frz)
-
+ xl_heap_freeze_tuple *frz, bool *totally_frozen_p)
{
bool changed = false;
bool freeze_xmax = false;
TransactionId xid;
+ bool totally_frozen = true;
frz->frzflags = 0;
frz->t_infomask2 = tuple->t_infomask2;
/* Process xmin */
xid = HeapTupleHeaderGetXmin(tuple);
- if (TransactionIdIsNormal(xid) &&
- TransactionIdPrecedes(xid, cutoff_xid))
+ if (TransactionIdIsNormal(xid))
{
- frz->t_infomask |= HEAP_XMIN_FROZEN;
- changed = true;
+ if (TransactionIdPrecedes(xid, cutoff_xid))
+ {
+ frz->t_infomask |= HEAP_XMIN_FROZEN;
+ changed = true;
+ }
+ else
+ totally_frozen = false;
}
/*
if (flags & FRM_MARK_COMMITTED)
frz->t_infomask &= HEAP_XMAX_COMMITTED;
changed = true;
+ totally_frozen = false;
}
else if (flags & FRM_RETURN_IS_MULTI)
{
frz->xmax = newxmax;
changed = true;
+ totally_frozen = false;
}
else
{
Assert(flags & FRM_NOOP);
}
}
- else if (TransactionIdIsNormal(xid) &&
- TransactionIdPrecedes(xid, cutoff_xid))
+ else if (TransactionIdIsNormal(xid))
{
- freeze_xmax = true;
+ if (TransactionIdPrecedes(xid, cutoff_xid))
+ freeze_xmax = true;
+ else
+ totally_frozen = false;
}
if (freeze_xmax)
if (tuple->t_infomask & HEAP_MOVED)
{
xid = HeapTupleHeaderGetXvac(tuple);
- if (TransactionIdIsNormal(xid) &&
- TransactionIdPrecedes(xid, cutoff_xid))
+ /*
+ * For Xvac, we ignore the cutoff_xid and just always perform the
+ * freeze operation. The oldest release in which such a value can
+ * actually be set is PostgreSQL 8.4, because old-style VACUUM FULL
+ * was removed in PostgreSQL 9.0. Note that if we were to respect
+ * cutoff_xid here, we'd need to make surely to clear totally_frozen
+ * when we skipped freezing on that basis.
+ */
+ if (TransactionIdIsNormal(xid))
{
/*
* If a MOVED_OFF tuple is not dead, the xvac transaction must
}
}
+ *totally_frozen_p = totally_frozen;
return changed;
}
{
xl_heap_freeze_tuple frz;
bool do_freeze;
+ bool tuple_totally_frozen;
do_freeze = heap_prepare_freeze_tuple(tuple, cutoff_xid, cutoff_multi,
- &frz);
+ &frz, &tuple_totally_frozen);
/*
* Note that because this is not a WAL-logged operation, we don't need to