On 01/02/2014 02:53 PM, Robert Haas wrote:
> On Tue, Dec 31, 2013 at 4:12 AM, Peter Geoghegan <pg@heroku.com> wrote:
>> On Tue, Dec 31, 2013 at 12:52 AM, Heikki Linnakangas
>> <hlinnakangas@vmware.com> wrote:
>>> 1. PromiseTupleInsertionLockAcquire(<my xid>)
>>> 2. Insert heap tuple
>>> 3. Insert index tuples
>>> 4. Check if conflict happened. Kill the already-inserted tuple on conflict.
>>> 5. PromiseTupleInsertionLockRelease(<my xid>)
>>>
>>> IOW, the only change to the current patch is that you acquire the new kind
>>> of lock before starting the insertion, and you release it after you've
>>> killed the tuple, or you know you're not going to kill it.
>>
>> Where does row locking fit in there? - you may need to retry when that
>> part is incorporated, of course. What if you have multiple promise
>> tuples from a contended attempt to insert a single slot, or multiple
>> broken promise tuples across multiple slots or even multiple commands
>> in the same xact?
You can only have one speculative insertion in progress at a time. After
you've done all the index insertions and checked that you really didn't
conflict with anyone, you're not going to go back and kill the tuple
anymore. After that point, the insertion is not speculation anymore.
> Yeah, it seems like PromiseTupleInsertionLockAcquire should be locking
> the tuple, rather than the XID.
Well, that would be ideal, because we already have tuple locks. It would
be nice to use the same concept for this. It's a bit tricky, however. I
guess the most straightforward way to do it would be to grab a
heavy-weight lock after you've inserted the tuple, but before releasing
the buffer lock. I don't immediately see a problem with that, although
it's a bit scary to acquire a heavy-weight lock while holding a buffer lock.
- Heikki