Bug #56251 | Deadlock with INSERT DELAYED and MERGE tables | ||
---|---|---|---|
Submitted: | 25 Aug 2010 13:21 | Modified: | 20 Nov 2010 22:59 |
Reporter: | Jon Olav Hauglid | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Locking | Severity: | S3 (Non-critical) |
Version: | 5.5 | OS: | Any |
Assigned to: | Dmitry Lenev | CPU Architecture: | Any |
[25 Aug 2010 13:21]
Jon Olav Hauglid
[13 Sep 2010 20:13]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/118115 3136 Dmitry Lenev 2010-09-14 Fix for bug #56251 "Deadlock with INSERT DELAYED and MERGE tables". Attempt to issue INSERT DELAYED statement for MERGE table might have ended with a deadlock if it has happened as part of transaction or under LOCK TABLES and there was a concurrent DDL or LOCK TABLES ... WRITE statement which tried to lock one of its underlying tables. The problem occurred when delayed insert handler thread tried to open MERGE table and discovered that to do this it has also to open all underlying tables as well and hence acquire metadata locks on them. Since metadata locks on underlying tables were not pre-acquired by a connection thread executing INSERT DELAYED attempt to do so might have led to waiting. In this case connection thread had to wait for delayed insert thread. If thread which was preventing lock on underlying table from being acquired had to wait for the connection thread (due to this or other metadata lock it had) a deadlock has occurred. This deadlock was not detected by MDL deadlock detector since wait for the handler thread by connection thread is not represented in wait-for graph. This patch solves this problem by ensuring that the delayed insert handler thread never tries to open underlying tables of a MERGE table. Instead open_tables() process is aborted right after parent table is open and ER_DELAYED_NOT_SUPPORTED error is emitted (which is passed to connection thread and ultimately to user). @ mysql-test/r/merge.result Added test for bug #56251 "Deadlock with INSERT DELAYED and MERGE tables". @ mysql-test/t/merge.test Added test for bug #56251 "Deadlock with INSERT DELAYED and MERGE tables". @ sql/sql_base.cc Changed open_n_lock_single_table() to take prelocking strategy as an argument instead of always using DML_prelocking_strategy. @ sql/sql_base.h Changed open_n_lock_single_table() to take prelocking strategy as an argument instead of always using DML_prelocking_strategy. Added a version of this function which is compatible with old signature. @ sql/sql_insert.cc When opening MERGE table in delayed insert thread stop and emit ER_DELAYED_NOT_SUPPORTED right after opening main table and before opening underlying tables. This ensures that we won't try to acquire metadata lock on underlying tables which might lead to a deadlock. This is achieved by using special prelocking strategy which abort open_tables() process as soon as we discover that we have opened table with engine which doesn't support delayed inserts.
[15 Sep 2010 14:16]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/118312 3137 Dmitry Lenev 2010-09-15 Fix for bug #56251 "Deadlock with INSERT DELAYED and MERGE tables". Attempting to issue an INSERT DELAYED statement for a MERGE table might have caused a deadlock if it happened as part of a transaction or under LOCK TABLES, and there was a concurrent DDL or LOCK TABLES ... WRITE statement which tried to lock one of its underlying tables. The problem occurred when a delayed insert handler thread tried to open a MERGE table and discovered that to do this it had also to open all underlying tables and hence acquire metadata locks on them. Since metadata locks on the underlying tables were not pre-acquired by the connection thread executing INSERT DELAYED, attempts to do so might lead to waiting. In this case the connection thread had to wait for the delayed insert thread. If the thread which was preventing the lock on the underlying table from being acquired had to wait for the connection thread (due to this or other metadata locks), a deadlock occurred. This deadlock was not detected by the MDL deadlock detector since waiting for the handler thread by the connection thread is not represented in the wait-for graph. This patch solves the problem by ensuring that the delayed insert handler thread never tries to open underlying tables of a MERGE table. Instead open_tables() is aborted right after the parent table is opened and a ER_DELAYED_NOT_SUPPORTED error is emitted (which is passed to the connection thread and ultimately to the user). @ mysql-test/r/merge.result Added test for bug #56251 "Deadlock with INSERT DELAYED and MERGE tables". @ mysql-test/t/merge.test Added test for bug #56251 "Deadlock with INSERT DELAYED and MERGE tables". @ sql/sql_base.cc Changed open_n_lock_single_table() to take prelocking strategy as an argument instead of always using DML_prelocking_strategy. @ sql/sql_base.h Changed open_n_lock_single_table() to take prelocking strategy as an argument instead of always using DML_prelocking_strategy. Added a version of this function which is compatible with old signature. @ sql/sql_insert.cc When opening MERGE table in delayed insert thread stop and emit ER_DELAYED_NOT_SUPPORTED right after opening main table and before opening underlying tables. This ensures that we won't try to acquire metadata lock on underlying tables which might lead to a deadlock. This is achieved by using special prelocking strategy which abort open_tables() process as soon as we discover that we have opened table with engine which doesn't support delayed inserts.
[4 Nov 2010 1:46]
Paul DuBois
Noted in 5.5.7 changelog. An INSERT DELAYED statement for a MERGE table could cause deadlock if it occurred as part of a transaction or under LOCK TABLES, and there was a concurrent DDL or LOCK TABLES ... WRITE statement that tried to lock one of its underlying tables.
[9 Nov 2010 19:43]
Bugs System
Pushed into mysql-5.5 5.5.7-rc (revid:sunanda.menon@sun.com-20101109182959-otkxq8vo2dcd13la) (version source revid:marko.makela@oracle.com-20100824081003-v4ecy0tga99cpxw2) (merge vers: 5.1.50) (pib:21)
[13 Nov 2010 16:19]
Bugs System
Pushed into mysql-trunk 5.6.99-m5 (revid:alexander.nozdrin@oracle.com-20101113155825-czmva9kg4n31anmu) (version source revid:marko.makela@oracle.com-20100824081003-v4ecy0tga99cpxw2) (merge vers: 5.1.50) (pib:21)
[13 Nov 2010 16:29]
Bugs System
Pushed into mysql-next-mr (revid:alexander.nozdrin@oracle.com-20101113160336-atmtmfb3mzm4pz4i) (version source revid:marko.makela@oracle.com-20100824081003-v4ecy0tga99cpxw2) (pib:21)