Bug #51086 | last deadlock detected not showing a valid reason for the deadlock | ||
---|---|---|---|
Submitted: | 11 Feb 2010 11:11 | Modified: | 11 Feb 2010 16:49 |
Reporter: | walid bakkar | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Locking | Severity: | S2 (Serious) |
Version: | 5.0.51a | OS: | Linux |
Assigned to: | CPU Architecture: | Any |
[11 Feb 2010 11:11]
walid bakkar
[11 Feb 2010 12:49]
Valeriy Kravchuk
Thank you for the problem report. Do you have any triggers defined on the FIELD table?
[11 Feb 2010 13:03]
walid bakkar
no, no triggers defined on FIELD and no triggers defined on DOCUMENT
[11 Feb 2010 13:21]
Valeriy Kravchuk
Please, send the results of: explain SELECT * FROM FIELD WHERE docid IN ( SELECT docid FROM DOCUMENT WHERE ( rootkey = '326E8341A9F8DFA7769590A7D35276E4' AND language = 'en' ) order by docid asc ); Note also this (http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html): "If a secondary index is used in a search and index record locks to be set are exclusive, InnoDB also retrieves the corresponding clustered index records and sets locks on them." Looks like this is the reason why X locks are set on the primary key of the DOCUMENT table that is used only in subquery of your DELETE in the first transaction.
[11 Feb 2010 13:27]
walid bakkar
explain SELECT * FROM FIELD WHERE docid IN ( SELECT docid FROM DOCUMENT WHERE ( rootkey = '326E8341A9F8DFA7769590A7D35276E4' AND language = 'en' ) order by docid asc ); +----+--------------------+----------+-----------------+------------------------------------------------------------+---------+---------+------+--------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+----------+-----------------+------------------------------------------------------------+---------+---------+------+--------+-------------+ | 1 | PRIMARY | FIELD | ALL | NULL | NULL | NULL | NULL | 110035 | Using where | | 2 | DEPENDENT SUBQUERY | DOCUMENT | unique_subquery | PRIMARY,rootkey,language_index,dockey_versionnumber_unique | PRIMARY | 4 | func | 1 | Using where | +----+--------------------+----------+-----------------+------------------------------------------------------------+---------+---------+------+--------+-------------+
[11 Feb 2010 13:29]
walid bakkar
(while i read the rest of your comment :) )
[11 Feb 2010 13:40]
walid bakkar
plan already looks like it isn't doing the best query for this deletion, as it is starting by doing a: +----+-------------+----------+------+----------------------------------------------------+---------+---------+-------------+------+------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+------+----------------------------------------------------+---------+---------+-------------+------+------------------------------------------+ | 1 | SIMPLE | DOCUMENT | ref | rootkey,language_index,dockey_versionnumber_unique | rootkey | 104 | const,const | 1 | Using where; Using index; Using filesort | +----+-------------+----------+------+----------------------------------------------------+---------+---------+-------------+------+------------------------------------------+ on the inner query, and them applying the FIELD IN on the small result it will get back. as for: "If a secondary index is used in a search and index record locks to be set are exclusive, InnoDB also retrieves the corresponding clustered index records and sets locks on them." i'm not sure this is the case, as none of the records in the FIELD table should match both rows on the DOCUMENT table the docid in the document is unique, the field rows are identified by the docid. so it sounds more like a transaction is setting locks on rows it might have encountered but not on the "corresponding" records only.
[11 Feb 2010 13:52]
Valeriy Kravchuk
So, actually for DELETE server reads entire FIELD table and then search in the other table by PRIMARY key, docid, just to find (in all cases but one) that it does NOT correspond. Surely it sets too many X locks and can deadlock easily with that other SELECT ... FOR UPDATE, that access rows by unique index, but has to set X locks on PRIMARY key also. Note this (from the same manual page I had quoted): "A locking read, an UPDATE, or a DELETE generally set record locks on every index record that is scanned in the processing of the SQL statement. It does not matter whether there are WHERE conditions in the statement that would exclude the row." To summarize: the reason for this deadlock is clear.
[11 Feb 2010 16:49]
walid bakkar
thanks for the quick feedback on this. so the problem now is that the deadlock is explainable, only because the wrong plan is picked for the execution of this query. as the plan shows, the field table is going to be scanned, and the subquery will be executed for every row, instead of executing the subquery first, and then deleting, using the docid index.