Andres Freund <andres@2ndquadrant.com> wrote:
> HeapTupleHeaderGetUpdateXid() ignores aborted updaters
> and returns InvalidTransactionId in that case, but
> HeapTupleSatisfiesVacuum() returns HEAPTUPLE_DELETE_IN_PROGRESS...
That sure *sounds* like it should cause a problem for this code in
CheckForSerializableConflictOut():
htsvResult = HeapTupleSatisfiesVacuum(tuple, TransactionXmin, buffer);
switch (htsvResult)
{
[ ... ]
case HEAPTUPLE_DELETE_IN_PROGRESS:
xid = HeapTupleHeaderGetUpdateXid(tuple->t_data);
break;
[ ... ]
}
Assert(TransactionIdIsValid(xid));
... however, I have not been able to trigger that Assert even with
gdb breakpoints at what I think are the right spots. Any
suggestions? How far back is it true that the above
HeapTupleSatisfiesVacuum() can return HEAPTUPLE_DELETE_IN_PROGRESS
but HeapTupleHeaderGetUpdateXid(tuple->t_data) on the exact same
tuple structure can return InvalidTransactionId? Is there some
other condition (besides a ROLLBACK of an UPDATE on the tuple being
read) which needs to be met? Is any particular timing necessary?
--
Kevin Grittner
EDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company