On 2013-11-25 12:36:19 -0300, Alvaro Herrera wrote:
> > 2) we frequently error out in heap_lock_updated_tuple_rec() with
> > ERROR: unable to fetch updated version of tuple
> >
> > That's because when we're following a ctid chain, it's perfectly
> > possible for the updated version of a tuple to already have been
> > vacuumed/pruned away if the the updating transaction has aborted.
> >
> > Also looks like a 9.3+ issues to me, slightly higher impact, but in the
> > end you're just getting some errors under concurrency.
>
> Yes, I think this is 9.3 only. First attachment shows my proposed
> patch, which is just to report success to caller in case the tuple
> cannot be acquired by heap_fetch. This is OK because if by the time we
> check the updated version of a tuple it is gone, it means there is no
> further update chain to follow and lock.
Looks good.
> > 1) (takes a bit)
> > TRAP: FailedAssertion("!(((xid) >= ((TransactionId) 3)))", File:/pruneheap.c", Line: 601)
> >
> > That's because HeapTupleHeaderGetUpdateXid() ignores aborted updaters
> > and returns InvalidTransactionId in that case, but
> > HeapTupleSatisfiesVacuum() returns HEAPTUPLE_DELETE_IN_PROGRESS...
>
> Interesting. This is a very narrow race condition: when we call
> HeapTupleSafisfiesVacuum the updater is still running, so it returns
> HEAPTUPLE_DELETE_IN_PROGRESS; but it aborts just before we read the
> tuple's update Xid.
Well, it's not *that* narrow - remember that a transaction is marked as
aborted in the clog *before* it is removed from the proc array.
> There is no way to close the window, but there is no need; if the
> updater aborted, we don't need to mark the page prunable in the first
> place. So we can just check the return value of
> HeapTupleHeaderGetUpdateXid and if it's InvalidXid, don't set the
> prunable bit. The second attachment below fixes the bug that way.
I am not sure I like the fact that HeapTupleHeaderGetUpdateXid() checks
for aborted transactions in the first place. Why is that a good idea?
ISTM that wanders off a fair bit from the other HeapTupleHeaderGet*
macros.
Greetings,
Andres Freund
-- Andres Freund http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services