Marko Tiikkaja wrote:
> On 2016-08-10 19:28, Alvaro Herrera wrote:
> >Umm. AFAICS HeapTupleSatisfiesUpdate() only returns SelfUpdated after
> >already calling HeapTupleHeaderGetCmax() (which obviously hasn't caught
> >the same assertion). Something is odd there ...
>
> HeapTupleSatisfiesUpdate() returns HeapTupleBeingUpdated in this case.
> HeapTupleSelfUpdated comes from here (line 4749):
>
> /* if there are updates, follow the update chain */
> if (follow_updates && !HEAP_XMAX_IS_LOCKED_ONLY(infomask))
> {
> HTSU_Result res;
> res = heap_lock_updated_tuple(relation, tuple, &t_ctid,
> GetCurrentTransactionId(),
> mode);
> if (res != HeapTupleMayBeUpdated)
> {
> result = res;
> /* recovery code expects to have buffer lock held */
> LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);
> goto failed;
> }
> }
Oh, I see ... so there's an update chain, and you're updating a earlier
tuple. But the later tuple has a multixact and one of the members is
the current transaction.
I wonder how can you lock a tuple that's not the latest, where that
update chain was produced by your own transaction. I suppose this is
because of plpgsql use of cursors.
--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services