mirror of
https://github.com/postgres/postgres.git
synced 2025-12-21 05:21:08 +03:00
heapam: Move logic to handle HEAP_MOVED into a helper function
Before we dealt with this in 6 near identical and one very similar copy. The helper function errors out when encountering a HEAP_MOVED_IN/HEAP_MOVED_OUT tuple with xvac considered current or in-progress. It'd be preferrable to do that change separately, but otherwise it'd not be possible to deduplicate the handling in HeapTupleSatisfiesVacuum(). Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Discussion: https://postgr.es/m/lxzj26ga6ippdeunz6kuncectr5gfuugmm2ry22qu6hcx6oid6@lzx3sjsqhmt6 Discussion: https://postgr.es/m/6rgb2nvhyvnszz4ul3wfzlf5rheb2kkwrglthnna7qhe24onwr@vw27225tkyar
This commit is contained in:
@@ -144,6 +144,55 @@ HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
|
|||||||
SetHintBits(tuple, buffer, infomask, xid);
|
SetHintBits(tuple, buffer, infomask, xid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If HEAP_MOVED_OFF or HEAP_MOVED_IN are set on the tuple, remove them and
|
||||||
|
* adjust hint bits. See the comment for SetHintBits() for more background.
|
||||||
|
*
|
||||||
|
* This helper returns false if the row ought to be invisible, true otherwise.
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
HeapTupleCleanMoved(HeapTupleHeader tuple, Buffer buffer)
|
||||||
|
{
|
||||||
|
TransactionId xvac;
|
||||||
|
|
||||||
|
/* only used by pre-9.0 binary upgrades */
|
||||||
|
if (likely(!(tuple->t_infomask & (HEAP_MOVED_OFF | HEAP_MOVED_IN))))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
xvac = HeapTupleHeaderGetXvac(tuple);
|
||||||
|
|
||||||
|
if (TransactionIdIsCurrentTransactionId(xvac))
|
||||||
|
elog(ERROR, "encountered tuple with HEAP_MOVED considered current");
|
||||||
|
|
||||||
|
if (TransactionIdIsInProgress(xvac))
|
||||||
|
elog(ERROR, "encountered tuple with HEAP_MOVED considered in-progress");
|
||||||
|
|
||||||
|
if (tuple->t_infomask & HEAP_MOVED_OFF)
|
||||||
|
{
|
||||||
|
if (TransactionIdDidCommit(xvac))
|
||||||
|
{
|
||||||
|
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||||
|
InvalidTransactionId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||||
|
InvalidTransactionId);
|
||||||
|
}
|
||||||
|
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||||
|
{
|
||||||
|
if (TransactionIdDidCommit(xvac))
|
||||||
|
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||||
|
InvalidTransactionId);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||||
|
InvalidTransactionId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HeapTupleSatisfiesSelf
|
* HeapTupleSatisfiesSelf
|
||||||
@@ -179,45 +228,8 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer)
|
|||||||
if (HeapTupleHeaderXminInvalid(tuple))
|
if (HeapTupleHeaderXminInvalid(tuple))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
if (!HeapTupleCleanMoved(tuple, buffer))
|
||||||
if (tuple->t_infomask & HEAP_MOVED_OFF)
|
return false;
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
return false;
|
|
||||||
if (!TransactionIdIsInProgress(xvac))
|
|
||||||
{
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
|
||||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (!TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
{
|
|
||||||
if (TransactionIdIsInProgress(xvac))
|
|
||||||
return false;
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
||||||
{
|
{
|
||||||
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
|
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
|
||||||
@@ -372,45 +384,8 @@ HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot,
|
|||||||
if (HeapTupleHeaderXminInvalid(tuple))
|
if (HeapTupleHeaderXminInvalid(tuple))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
if (!HeapTupleCleanMoved(tuple, buffer))
|
||||||
if (tuple->t_infomask & HEAP_MOVED_OFF)
|
return false;
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
return false;
|
|
||||||
if (!TransactionIdIsInProgress(xvac))
|
|
||||||
{
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
|
||||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (!TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
{
|
|
||||||
if (TransactionIdIsInProgress(xvac))
|
|
||||||
return false;
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An invalid Xmin can be left behind by a speculative insertion that
|
* An invalid Xmin can be left behind by a speculative insertion that
|
||||||
@@ -468,45 +443,8 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
|
|||||||
if (HeapTupleHeaderXminInvalid(tuple))
|
if (HeapTupleHeaderXminInvalid(tuple))
|
||||||
return TM_Invisible;
|
return TM_Invisible;
|
||||||
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
else if (!HeapTupleCleanMoved(tuple, buffer))
|
||||||
if (tuple->t_infomask & HEAP_MOVED_OFF)
|
return TM_Invisible;
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
return TM_Invisible;
|
|
||||||
if (!TransactionIdIsInProgress(xvac))
|
|
||||||
{
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return TM_Invisible;
|
|
||||||
}
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
|
||||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (!TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
{
|
|
||||||
if (TransactionIdIsInProgress(xvac))
|
|
||||||
return TM_Invisible;
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return TM_Invisible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
||||||
{
|
{
|
||||||
if (HeapTupleHeaderGetCmin(tuple) >= curcid)
|
if (HeapTupleHeaderGetCmin(tuple) >= curcid)
|
||||||
@@ -756,45 +694,8 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
|
|||||||
if (HeapTupleHeaderXminInvalid(tuple))
|
if (HeapTupleHeaderXminInvalid(tuple))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
if (!HeapTupleCleanMoved(tuple, buffer))
|
||||||
if (tuple->t_infomask & HEAP_MOVED_OFF)
|
return false;
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
return false;
|
|
||||||
if (!TransactionIdIsInProgress(xvac))
|
|
||||||
{
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
|
||||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (!TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
{
|
|
||||||
if (TransactionIdIsInProgress(xvac))
|
|
||||||
return false;
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
||||||
{
|
{
|
||||||
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
|
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
|
||||||
@@ -979,45 +880,8 @@ HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
|
|||||||
if (HeapTupleHeaderXminInvalid(tuple))
|
if (HeapTupleHeaderXminInvalid(tuple))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
if (!HeapTupleCleanMoved(tuple, buffer))
|
||||||
if (tuple->t_infomask & HEAP_MOVED_OFF)
|
return false;
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
return false;
|
|
||||||
if (!XidInMVCCSnapshot(xvac, snapshot))
|
|
||||||
{
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
|
||||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (!TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
{
|
|
||||||
if (XidInMVCCSnapshot(xvac, snapshot))
|
|
||||||
return false;
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
||||||
{
|
{
|
||||||
if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)
|
if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)
|
||||||
@@ -1222,43 +1086,8 @@ HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *de
|
|||||||
{
|
{
|
||||||
if (HeapTupleHeaderXminInvalid(tuple))
|
if (HeapTupleHeaderXminInvalid(tuple))
|
||||||
return HEAPTUPLE_DEAD;
|
return HEAPTUPLE_DEAD;
|
||||||
/* Used by pre-9.0 binary upgrades */
|
else if (!HeapTupleCleanMoved(tuple, buffer))
|
||||||
else if (tuple->t_infomask & HEAP_MOVED_OFF)
|
return HEAPTUPLE_DEAD;
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
return HEAPTUPLE_DELETE_IN_PROGRESS;
|
|
||||||
if (TransactionIdIsInProgress(xvac))
|
|
||||||
return HEAPTUPLE_DELETE_IN_PROGRESS;
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return HEAPTUPLE_DEAD;
|
|
||||||
}
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
}
|
|
||||||
/* Used by pre-9.0 binary upgrades */
|
|
||||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
|
||||||
{
|
|
||||||
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
|
|
||||||
|
|
||||||
if (TransactionIdIsCurrentTransactionId(xvac))
|
|
||||||
return HEAPTUPLE_INSERT_IN_PROGRESS;
|
|
||||||
if (TransactionIdIsInProgress(xvac))
|
|
||||||
return HEAPTUPLE_INSERT_IN_PROGRESS;
|
|
||||||
if (TransactionIdDidCommit(xvac))
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
|
||||||
InvalidTransactionId);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
|
||||||
InvalidTransactionId);
|
|
||||||
return HEAPTUPLE_DEAD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
|
||||||
{
|
{
|
||||||
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
|
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
|
||||||
|
|||||||
Reference in New Issue
Block a user