On 17.12.2010 18:44, Florian Pflug wrote:
On Dec17, 2010, at 16:49 , Heikki Linnakangas wrote:
On 15.12.2010 16:20, Florian Pflug wrote:
On Dec14, 2010, at 15:01 , Robert Haas wrote:
On Tue, Dec 14, 2010 at 7:51 AM, Florian Pflug<f...@phlo.org>   wrote:
- serializable lock consistency - I am fairly certain this needs
rebasing.  I don't have time to deal with it right away.  That sucks,
because I think this is a really important change.
I can try to find some time to update the patch if it suffers from bit-rot. 
Would that help?

Yes!

I've rebased the patch to the current HEAD, and re-run my FK concurrency test 
suite,
available from https://github.com/fgp/fk_concurrency, to verify that things 
still work.

I've also asserts to the callers of heap_{update,delete,lock_tuple} to verify 
(and document)
that update_xmax may only be InvalidTransactionId if a lockcheck_snapshot is 
passed to
heap_{update,delete,lock_tuple}.

Finally, I've improved the explanation in src/backend/executor/README of how 
row locks and
REPEATABLE READ transactions interact, and tried to state the guarantees 
provided by
FOR SHARE and FOR UPDATE locks more precisely.

I've published my work to 
https://github.com/fgp/postgres/tree/serializable_lock_consistency,
and attached an updated patch. I'd be happy to give write access to that GIT 
repository
to anyone who wants to help getting this committed.

Here's some typo&  style fixes for that, also available at 
git://git.postgresql.org/git/users/heikki/postgres.git.

Thanks! FYI, I've pulled these into 
https://github.com/fgp/postgres/tree/serializable_lock_consistency

I think this patch is in pretty good shape now.

The one thing I'm not too happy with is the API for heap_update/delete/lock_tuple. The return value is:

 * Normal, successful return value is HeapTupleMayBeUpdated, which
 * actually means we *did* update it.  Failure return codes are
 * HeapTupleSelfUpdated, HeapTupleUpdated, or HeapTupleBeingUpdated
 * (the last only possible if wait == false).

And:

 * In the failure cases, the routine returns the tuple's t_ctid and t_max
 * in ctid and update_xmax.
 * If ctid is the same as t_self and update_xmax a valid transaction id,
 *      the tuple was deleted.
 * If ctid differs from t_self, the tuple was updated, ctid is the location
* of the replacement tuple and update_xmax is the updating transaction's xid. * update_xmax must in this case be used to verify that the replacement tuple
 *      matched.
 * Otherwise, if ctid is the same as t_self and update_xmax is
 *      InvalidTransactionId, the tuple was neither replaced nor deleted, but
 *      locked by a transaction invisible to lockcheck_snapshot. This case can
 *      thus only arise if lockcheck_snapshot is a valid snapshot.

That's quite complicated. I think we should bite the bullet and add a couple of more return codes to explicitly tell the caller what happened. I propose:

HeapTupleMayBeUpdated- the tuple was actually updated (same as before)
HeapTupleSelfUpdated - the tuple was updated by a later command in same xact (same as before)
HeapTupleBeingUpdated - concurrent update in progress (same as before)
HeapTupleUpdated - the tuple was updated by another xact. *update_xmax and *ctid are set to point to the replacement tuple.
HeapTupleDeleted - the tuple was deleted by another xact
HeapTupleLocked - lockcheck_snapshot was given, and the tuple was locked by another xact

I'm not sure how to incorporate that into the current heap_delete/update/lock_tuple functions and HeapTupleSatisfiesUpdate. It would be nice to not copy-paste the logic to handle those into all three functions. Perhaps that common logic starting with the HeapTupleSatisfiesUpdate() call could be pulled into a common function.

--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to