On Sun, Sep 8, 2013 at 10:21 PM, Peter Geoghegan <p...@heroku.com> wrote: > This necessitated inventing entirely new LWLock semantics around > "weakening" (from exclusive to shared) and "strengthening" (from > shared to exclusive) of locks already held. Of course, as you'd > expect, there are some tricky race hazards surrounding these new > functions that clients need to be mindful of. These have been > documented within lwlock.c.
I've since found that I can fairly reliably get this to deadlock at high client counts (say, 95, which will do it on my 4 core laptop with a little patience). To get this to happen, I used pgbench with a single INSERT...ON DUPLICATE KEY IGNORE transaction script. The more varied workload that I tested this most recent revision (v2) with the most, with a transaction consisting on a mixture of different statements (UPDATEs, DELETEs, INSERT...ON DUPLICATE KEY LOCK FOR UPDATE) did not show the problem. What I've been doing to recreate this is pgbench runs in an infinite loop from a bash script, with a new table created for each iteration. Each iteration has 95 clients "speculatively insert" a total of 1500 possible tuples for 15 seconds. After this period, the table has exactly 1500 tuples, with primary key values 1 - 1500. Usually, after about 5 - 20 minutes, deadlock occurs. This was never a problem with the exclusive lock coding (v1), unsurprisingly - after all, as far as buffer locks are concerned, it did much the same thing as the existing code. I've made some adjustments to LWLockWeaken, LWLockStrengthen and LWLockRelease that made the deadlocks go away. Or at least, no deadlocks or other problems manifested themselves using the same test case for over two hours. Attached revision includes these changes, as well as a few minor comment tweaks here and there. I am working on an analysis of the broader deadlock hazards - the implications of simultaneously holding multiple shared buffer locks (that is, one for every unique index btree leaf page participating in value locking) for the duration of a each heap tuple insertion (each heap_insert() call). I'm particularly looking for unexpected ways in which this locking could interact with other parts of the code that also acquire buffer locks, for example vacuumlazy.c. I'll also try and estimate how much of a maintainability burden unexpected locking interactions with these other subsystems might be. In case it isn't obvious, the deadlocking issue addressed by this revision is not inherent to my design or anything like that - the bugs fixed by this revision are entirely confined to lwlock.c. -- Peter Geoghegan
insert_on_dup.v3.2013_09_10.patch.gz
Description: GNU Zip compressed data
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers