Patchers,
A first sketch of this. It actually works as expected -- in particular,
foreign key checking no longer blocks, and of course concurrent updates
or deletes of two tuples in opposite order reports a deadlock (I was
confused at first seeing so many "deadlock detected" in my test programs
until I realized they also happen on CVS HEAD ... doh!)
I implemented the user-visible side of this (FKs in particular) using a
new "FOR SHARE" clause to SELECT. This is of course open to
suggestions. Inside the grammar I hacked it using the productions for
FOR UPDATE, and stashed a String as the first node of the relid List.
I got rid of heap_mark4update and replaced it with heap_locktuple, which
in turn calls LockTuple (and corresponding ConditionalLockTuple). There
is also an unused UnlockTuple. I somewhat changed the locking rules
described in backend/storage/buffer/README:
1. To examine a tuple one must first call LockTuple, which grabs a pin
and lock in the buffer. The buffer lock is released right away, but the
pin is kept.
2. Unchanged (one can examine the tuple as long as the pin is held)
3. With an exclusive lock on the tuple, one can change (xmin/xmax)
fields on the tuple; no lock on the buffer is necessary.
4. With a shared lock on the tuple, one can change commit status bits;
no lock on the buffer is necessary.
5. Unchanged (to remove a tuple, LockBufferForCleanup is needed).
Still missing is the ability of lmgr to spill to disk. I plan to do
this using the slru mechanism or something similar; I ditched the idea
of establishing a method to be used by the deferred trigger queue, at
least for now.
Please comment.
--
Alvaro Herrera (<alvherre[@]dcc.uchile.cl>)
"If you have nothing to say, maybe you need just the right tool to help you
not say it." (New York Times, about Microsoft PowerPoint)