Re: INSERT...ON DUPLICATE KEY LOCK FOR UPDATE

From: Heikki Linnakangas <hlinnakangas(at)vmware(dot)com>
To: Peter Geoghegan <pg(at)heroku(dot)com>
Cc: Pg Hackers <pgsql-hackers(at)postgresql(dot)org>, Robert Haas <robertmhaas(at)gmail(dot)com>, Andres Freund <andres(at)2ndquadrant(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Subject: Re: INSERT...ON DUPLICATE KEY LOCK FOR UPDATE
Date: 2014-01-14 10:43:24
Message-ID: 52D514CC.2070907@vmware.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 01/14/2014 12:20 PM, Peter Geoghegan wrote:
> I think that the prevention of unprincipled deadlocking is all down to
> this immediately prior piece of code, at least in those test cases:

> ! /*
> ! * in insertion by other.
> ! *
> ! * Before returning true, check for the special case that the
> ! * tuple was deleted by the same transaction that inserted it.
> ! * Such a tuple will never be visible to anyone else, whether
> ! * the transaction commits or aborts.
> ! */
> ! if (!(tuple->t_infomask & HEAP_XMAX_INVALID) &&
> ! !(tuple->t_infomask & HEAP_XMAX_COMMITTED) &&
> ! !(tuple->t_infomask & HEAP_XMAX_IS_MULTI) &&
> ! !HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask) &&
> ! HeapTupleHeaderGetRawXmax(tuple) == HeapTupleHeaderGetRawXmin(tuple))
> ! {
> ! return false;
> ! }
>
> But why should it be acceptable to change the semantics of dirty
> snapshots like this, which previously always returned true when
> control reached here? It is a departure from their traditional
> behavior, not limited to clients of this new promise tuple
> infrastructure. Now, it becomes entirely a matter of whether we tried
> to insert before or after the deleting xact's deletion (of a tuple it
> originally inserted) as to whether or not we block. So in general we
> don't get to "keep our old value locks" until xact end when we update
> or delete.

Hmm. So the scenario would be that a process inserts a tuple, but kills
it again later in the transaction, and then re-inserts the same value.
The expectation is that because it inserted the value once already,
inserting it again will not block. Ie. inserting and deleting a tuple
effectively acquires a value-lock on the inserted values.

> Even if you don't consider this a bug for existing dirty
> snapshot clients (I myself do - we can't rely on deleting a row and
> re-inserting the same values now, which could be particularly
> undesirable for updates),

Yeah, it would be bad if updates start failing because of this. We could
add a check for that, and return true if the tuple was updated rather
than deleted.

> I have already described how we can take
> advantage of deleting tuples while still holding on to their "value
> locks" [1] to Andres. I think it'll be very important for multi-master
> conflict resolution. I've already described this useful property of
> dirty snapshots numerous times on this thread in relation to different
> aspects, as it happens. It's essential.

I didn't understand that description.

> Anyway, I guess you're going to need an infomask bit to fix this, so
> you can differentiate between 'promise' tuples and 'proper' tuples.

Yeah, that's one way. Or you could set xmin to invalid, to make the
killed tuple look thoroughly dead to everyone.

> Those are in short supply. I still think this problem is more or less
> down to a modularity violation, and I suspect that this is not the
> last problem that will be found along these lines if we continue to
> pursue this approach.

You have suspected that many times throughout this thread, and every
time there's been a relatively simple solutions to the issues you've
raised. I suspect that's also going to be true for whatever mundane next
issue you come up with.

- Heikki

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Marko Tiikkaja 2014-01-14 10:51:56 Re: plpgsql.consistent_into
Previous Message Mel Gorman 2014-01-14 10:21:43 Re: Linux kernel impact on PostgreSQL performance