Re: MultiXact bugs - Mailing list pgsql-hackers

From Andres Freund
Subject Re: MultiXact bugs
Date
Msg-id 20131125162655.GA7387@alap2.anarazel.de
Whole thread Raw
In response to Re: MultiXact bugs  (Alvaro Herrera <alvherre@2ndquadrant.com>)
Responses Re: MultiXact bugs  (Alvaro Herrera <alvherre@2ndquadrant.com>)
List pgsql-hackers
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



pgsql-hackers by date:

Previous
From: Fujii Masao
Date:
Subject: Re: session_preload_libraries not in sample config?
Next
From: Stephen Frost
Date:
Subject: Re: Extension Templates S03E11