Skip to content

Commit b8259e4

Browse files
committed
MDEV-19384 Deadlock in FTWRL
The deadlock happened between FTWRL under open HANDLER, LOCK TABLE and DROP DATABASE Fixed by reverting the previous fix for handler open in lock_global_read_lock() Fixed the original (wrong) test case in flush_read_lock.test to be repeatable.
1 parent 60bd353 commit b8259e4

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed

mysql-test/main/flush_read_lock.result

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,6 +1677,8 @@ set global sql_mode=default;
16771677
# Deadlock between FTWRL under open handler and DDL/LOCK TABLES
16781678
#
16791679
CREATE TABLE t1(a INT);
1680+
#
1681+
connect con3,localhost,root,,;
16801682
HANDLER t1 OPEN;
16811683
#
16821684
connect con1,localhost,root,,;
@@ -1692,7 +1694,10 @@ disconnect con2;
16921694
connection default;
16931695
FLUSH TABLES WITH READ LOCK;
16941696
UNLOCK TABLES;
1697+
#
1698+
connection con3;
16951699
HANDLER t1 CLOSE;
1700+
disconnect con3;
16961701
#
16971702
connection con1;
16981703
UNLOCK TABLES;
@@ -1727,3 +1732,31 @@ disconnect con1;
17271732
connection default;
17281733
DROP TABLE t1;
17291734
SET DEBUG_SYNC= 'RESET';
1735+
#
1736+
# MDEV-19384 Deadlock between FTWRL under open HANDLER, LOCK TABLE
1737+
# and DROP DATABASE
1738+
#
1739+
CREATE DATABASE mysqltest;
1740+
CREATE TABLE mysqltest.t1(a INT);
1741+
HANDLER mysqltest.t1 OPEN as t1;
1742+
connect con1,localhost,root,,;
1743+
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL ready';
1744+
LOCK TABLE mysqltest.t1 WRITE;
1745+
connect con2,localhost,root,,;
1746+
SET DEBUG_SYNC= 'now WAIT_FOR ready';
1747+
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL ready';
1748+
DROP DATABASE mysqltest;
1749+
connect con3,localhost,root,,;
1750+
SET DEBUG_SYNC= 'now WAIT_FOR ready';
1751+
disconnect con3;
1752+
connection default;
1753+
FLUSH TABLES WITH READ LOCK;
1754+
UNLOCK TABLES;
1755+
HANDLER t1 CLOSE;
1756+
connection con1;
1757+
UNLOCK TABLES;
1758+
disconnect con1;
1759+
connection con2;
1760+
disconnect con2;
1761+
connection default;
1762+
SET DEBUG_SYNC= 'RESET';

mysql-test/main/flush_read_lock.test

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,9 @@ set global sql_mode=default;
20232023
--echo # Deadlock between FTWRL under open handler and DDL/LOCK TABLES
20242024
--echo #
20252025
CREATE TABLE t1(a INT);
2026+
2027+
--echo #
2028+
connect (con3,localhost,root,,);
20262029
HANDLER t1 OPEN;
20272030

20282031
--echo #
@@ -2041,7 +2044,11 @@ disconnect con2;
20412044
connection default;
20422045
FLUSH TABLES WITH READ LOCK;
20432046
UNLOCK TABLES;
2047+
2048+
--echo #
2049+
connection con3;
20442050
HANDLER t1 CLOSE;
2051+
disconnect con3;
20452052

20462053
--echo #
20472054
connection con1;
@@ -2087,3 +2094,40 @@ disconnect con1;
20872094
connection default;
20882095
DROP TABLE t1;
20892096
SET DEBUG_SYNC= 'RESET';
2097+
2098+
--echo #
2099+
--echo # MDEV-19384 Deadlock between FTWRL under open HANDLER, LOCK TABLE
2100+
--echo # and DROP DATABASE
2101+
--echo #
2102+
2103+
CREATE DATABASE mysqltest;
2104+
CREATE TABLE mysqltest.t1(a INT);
2105+
HANDLER mysqltest.t1 OPEN as t1;
2106+
2107+
connect (con1,localhost,root,,);
2108+
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL ready';
2109+
--send LOCK TABLE mysqltest.t1 WRITE
2110+
connect (con2,localhost,root,,);
2111+
SET DEBUG_SYNC= 'now WAIT_FOR ready';
2112+
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL ready';
2113+
--send DROP DATABASE mysqltest
2114+
2115+
connect (con3,localhost,root,,);
2116+
SET DEBUG_SYNC= 'now WAIT_FOR ready';
2117+
disconnect con3;
2118+
2119+
connection default;
2120+
FLUSH TABLES WITH READ LOCK;
2121+
UNLOCK TABLES;
2122+
HANDLER t1 CLOSE;
2123+
connection con1;
2124+
2125+
--error 0,ER_NO_SUCH_TABLE
2126+
reap;
2127+
UNLOCK TABLES;
2128+
disconnect con1;
2129+
connection con2;
2130+
reap;
2131+
disconnect con2;
2132+
connection default;
2133+
SET DEBUG_SYNC= 'RESET';

sql/lock.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,12 @@ bool Global_read_lock::lock_global_read_lock(THD *thd)
10291029
DBUG_RETURN(1);
10301030
}
10311031

1032+
/*
1033+
Release HANDLER OPEN by the current THD as they may cause deadlocks
1034+
if another thread is trying to simultaneous drop the table
1035+
*/
1036+
mysql_ha_cleanup_no_free(thd);
1037+
10321038
DBUG_ASSERT(! thd->mdl_context.is_lock_owner(MDL_key::BACKUP, "", "",
10331039
MDL_BACKUP_FTWRL1));
10341040
DBUG_ASSERT(! thd->mdl_context.is_lock_owner(MDL_key::BACKUP, "", "",
@@ -1050,9 +1056,6 @@ bool Global_read_lock::lock_global_read_lock(THD *thd)
10501056

10511057
m_mdl_global_read_lock= mdl_request.ticket;
10521058
m_state= GRL_ACQUIRED;
1053-
1054-
/* Release HANDLER OPEN after we have got our MDL lock */
1055-
mysql_ha_cleanup_no_free(thd);
10561059
}
10571060
/*
10581061
We DON'T set global_read_lock_blocks_commit now, it will be set after

0 commit comments

Comments
 (0)