Re: Strange deadlock in foreign key check
От | Adrian Klaver |
---|---|
Тема | Re: Strange deadlock in foreign key check |
Дата | |
Msg-id | 55C4D126.3080508@aklaver.com обсуждение исходный текст |
Ответ на | Re: Strange deadlock in foreign key check (Sophia Wright <sjw9010@gmail.com>) |
Список | pgsql-general |
On 08/06/2015 04:24 PM, Sophia Wright wrote: > On Fri, Aug 7, 2015 at 2:46 AM, Adrian Klaver <adrian.klaver@aklaver.com > <mailto:adrian.klaver@aklaver.com>> wrote: > > I would also take a look at Alvaro's explanation. My understanding > is that for locking purposes the UNIQUE index is considered sort of > like a FK, as it could be used as a FK. This then leads to the FOR > UPDATE lock, which from Table 13.3 at the link I sent, conflicts > with all the other row locks. > > Like I said, I think it would make sense for a UNIQUE index in pk_rel, > i.e. the fk_rel insert would try to lock pk_rel.id <http://pk_rel.id> > with KEY SHARE, and would end up locking any other UNIQUE fields as a > result. > > But I can't see why the pk_rel deletion would want a KEY SHARE lock on > fk_rel. It must be using FOR KEY SHARE rather than FOR UPDATE, since it > does not conflict with the update of fk_rel.pk_id in the first example. > So why lock fk_rel at all, if the lock doesn't include fk_rel.pk_id? > Isn't that the only bit that matters to a pk_rel deletion? Well what I see below from the 10000 ft level: Session 1: =>begin; =>update fk_rel set x = 'b'; http://www.postgresql.org/docs/9.4/interactive/explicit-locking.html#LOCKING-ROWS "The FOR UPDATE lock mode is also acquired by any DELETE on a row, and also by an UPDATE that modifies the values on certain columns. Currently, the set of columns considered for the UPDATE case are those that have a unique index on them that can be used in a foreign key (so partial indexes and expressional indexes are not considered), but this may change in the future." You have a UNIQUE index on x, so when you UPDATE it you get a FOR UPDATE lock that from Table 13-3. Conflicting Row-level Locks conflicts with all other locks. Session 2: =>delete from pk_rel where id = 1; [Blocks waiting for Session 1] You want to DELETE from pk_rel an id that has a FK dependency to the row that is now locked above, so the DELETE waits pending the lock release above. Session 1: =>insert into fk_rel values (1, 'a'); [Blocks waiting for Session 2] You want to INSERT a row into fk_rel that has an pk_id that you are trying to DELETE above, so this is waiting to to see what the DELETE does and the DELETE is waiting to see what the UPDATE does and the INSERT is waiting to see what they both do. So until the UPDATE commits/rollbacks the DELETE and INSERT are stuck on what do about the DELETE id=1/ INSERT pk_id=1 dilemma. -- Adrian Klaver adrian.klaver@aklaver.com
В списке pgsql-general по дате отправления: