Re: Problems with approach #2 to value locking (INSERT ... ON CONFLICT UPDATE/IGNORE patch) - Mailing list pgsql-hackers
From | Heikki Linnakangas |
---|---|
Subject | Re: Problems with approach #2 to value locking (INSERT ... ON CONFLICT UPDATE/IGNORE patch) |
Date | |
Msg-id | 54A7B65F.1060009@vmware.com Whole thread Raw |
In response to | Re: Problems with approach #2 to value locking (INSERT ... ON CONFLICT UPDATE/IGNORE patch) (Peter Geoghegan <pg@heroku.com>) |
Responses |
Re: Problems with approach #2 to value locking (INSERT ... ON
CONFLICT UPDATE/IGNORE patch)
|
List | pgsql-hackers |
On 01/03/2015 02:43 AM, Peter Geoghegan wrote: > On Thu, Jan 1, 2015 at 11:17 PM, Peter Geoghegan <pg@heroku.com> wrote: >> I've been working on fixing the bugs that Jeff Janes found [1] with >> approach #2 to value locking [2]. Approach #1 was unaffected. > > Unfortunately, exclusion constraints (which only value locking > approach #2 has support for, for the IGNORE variant) are broken, even > with my fix for the largely unrelated issues also described in my > opening mail. I now believe that it is inherently impossible to > support exclusion constraints with INSERT ... ON CONFLICT IGNORE, if > we are insistent that there cannot be livelocks, unprincipled > deadlocks or spurious exclusion violations....and I think you all know > how I feel about those :-) . I think that we should drop support for > exclusion constraints, regardless of whatever else happens with value > locking. > > Previously, my mental model of approach #2 was that it more or less > handled B-Trees and exclusion constraint related indexes equivalently. > This is untrue, though. > > Today, in general, exclusion constraints more or less work by > physically inserting a heap tuple and index tuple relating to the > exclusion constraint (typically this is with a GiST index). There > could well be a conflict due to a concurrent insertion, or even due to > the fact that there was a conflicting tuple all along. The > implementation tries to find a conclusively committed conflicting > tuple. If it does not find such a tuple, it knows that its own already > physically inserted tuple is enough of a reason for others to have to > worry about it, and so it may proceed and commit the xact -- once it > does a whole index scan with only its own tuple found (and not any > overlapping tuple from an unfinished xact), it's clear that it can > proceed. > > Exclusion constraints are made to do a pre-check by approach #2 to > value locking, to do an IGNORE, but that isn't really significant > here. The reason that #2 is broken for exclusion constraints but not > for unique indexes is that unique index insertion reports a conflict > in the process of inserting. In contrast, unique constraints insert > optimistically, and re-check. What's the difference? Well, even though > (since the implementation passes UNIQUE_CHECK_PARTIAL for unique index > insertion) we still insert when there is a conflict, there is an > important distinction: Value locking. That is to say, even though we > still insert, we also still use buffer locks as value locks in the > usual way that unique indexes do (we hold an exclusion buffer lock on > the first B-Tree leaf page the value could be on, as always). We still > decide that there is no conflict when the is an exclusion buffer lock, > which is a sufficient choke point to make that determination > conclusive. This implies that even with many concurrent insertions > into a newly created table, there will definitely be one inserter that > conclusively does *not* have a conflict, while the others might > (depends on the status of the guy who conclusively had *no* conflict, > or his line of successor xacts that may or may not themselves commit). > > In a private e-mail to Heikki, I pointed out that he was mistaken when > he said that there is a pre-existing problem with exclusion > constraints: it is not possible for concurrent inserters to both > spuriously get exclusion violations when only one needs to. Heikki > accepted this. However, I now realize that Heikki was closer to being > right about it than I was; you can't get spurious exclusion > violations, but you can get something that's about the same, which is > a deadlock. That usually doesn't matter that much, because people > usually don't worry about the issue with exclusion constraints. But in > a world where they support INSERT ... ON CONFLICT IGNORE, that isn't > acceptable, IMV. > > I have a test case: > https://github.com/petergeoghegan/upsert/blob/master/exclusion.sh > > I see both spurious exclusion violations, and unprincipled deadlocks > with this simple IGNORE-based testcase, that uses a GiST + btree_gist > exclusion constraint. I didn't see livelocks, which would have been > really bad, because a mutual need to wait on each other's xact causes > a deadlock, and the deadlock detector detects those. I think that the > spurious exclusion violations are merely an artifact of the > implementation, as opposed to an inherent problem with exclusion > constraints (in other words, I don't withdraw my remarks from the last > paragraph - only (arguably) unprincipled deadlocks occur with ordinary > exclusion constraint enforcement with lots of concurrency). I read this email several times but could not understand. Please explain in words of one syllable how the deadlock arises. Then, please find a way to fix it. - Heikki
pgsql-hackers by date: