Commit b8259e4b authored by Monty's avatar Monty

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.
parent 60bd353b
......@@ -1677,6 +1677,8 @@ set global sql_mode=default;
# Deadlock between FTWRL under open handler and DDL/LOCK TABLES
#
CREATE TABLE t1(a INT);
#
connect con3,localhost,root,,;
HANDLER t1 OPEN;
#
connect con1,localhost,root,,;
......@@ -1692,7 +1694,10 @@ disconnect con2;
connection default;
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
#
connection con3;
HANDLER t1 CLOSE;
disconnect con3;
#
connection con1;
UNLOCK TABLES;
......@@ -1727,3 +1732,31 @@ disconnect con1;
connection default;
DROP TABLE t1;
SET DEBUG_SYNC= 'RESET';
#
# MDEV-19384 Deadlock between FTWRL under open HANDLER, LOCK TABLE
# and DROP DATABASE
#
CREATE DATABASE mysqltest;
CREATE TABLE mysqltest.t1(a INT);
HANDLER mysqltest.t1 OPEN as t1;
connect con1,localhost,root,,;
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL ready';
LOCK TABLE mysqltest.t1 WRITE;
connect con2,localhost,root,,;
SET DEBUG_SYNC= 'now WAIT_FOR ready';
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL ready';
DROP DATABASE mysqltest;
connect con3,localhost,root,,;
SET DEBUG_SYNC= 'now WAIT_FOR ready';
disconnect con3;
connection default;
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
HANDLER t1 CLOSE;
connection con1;
UNLOCK TABLES;
disconnect con1;
connection con2;
disconnect con2;
connection default;
SET DEBUG_SYNC= 'RESET';
......@@ -2023,6 +2023,9 @@ set global sql_mode=default;
--echo # Deadlock between FTWRL under open handler and DDL/LOCK TABLES
--echo #
CREATE TABLE t1(a INT);
--echo #
connect (con3,localhost,root,,);
HANDLER t1 OPEN;
--echo #
......@@ -2041,7 +2044,11 @@ disconnect con2;
connection default;
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
--echo #
connection con3;
HANDLER t1 CLOSE;
disconnect con3;
--echo #
connection con1;
......@@ -2087,3 +2094,40 @@ disconnect con1;
connection default;
DROP TABLE t1;
SET DEBUG_SYNC= 'RESET';
--echo #
--echo # MDEV-19384 Deadlock between FTWRL under open HANDLER, LOCK TABLE
--echo # and DROP DATABASE
--echo #
CREATE DATABASE mysqltest;
CREATE TABLE mysqltest.t1(a INT);
HANDLER mysqltest.t1 OPEN as t1;
connect (con1,localhost,root,,);
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL ready';
--send LOCK TABLE mysqltest.t1 WRITE
connect (con2,localhost,root,,);
SET DEBUG_SYNC= 'now WAIT_FOR ready';
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL ready';
--send DROP DATABASE mysqltest
connect (con3,localhost,root,,);
SET DEBUG_SYNC= 'now WAIT_FOR ready';
disconnect con3;
connection default;
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;
HANDLER t1 CLOSE;
connection con1;
--error 0,ER_NO_SUCH_TABLE
reap;
UNLOCK TABLES;
disconnect con1;
connection con2;
reap;
disconnect con2;
connection default;
SET DEBUG_SYNC= 'RESET';
......@@ -1029,6 +1029,12 @@ bool Global_read_lock::lock_global_read_lock(THD *thd)
DBUG_RETURN(1);
}
/*
Release HANDLER OPEN by the current THD as they may cause deadlocks
if another thread is trying to simultaneous drop the table
*/
mysql_ha_cleanup_no_free(thd);
DBUG_ASSERT(! thd->mdl_context.is_lock_owner(MDL_key::BACKUP, "", "",
MDL_BACKUP_FTWRL1));
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)
m_mdl_global_read_lock= mdl_request.ticket;
m_state= GRL_ACQUIRED;
/* Release HANDLER OPEN after we have got our MDL lock */
mysql_ha_cleanup_no_free(thd);
}
/*
We DON'T set global_read_lock_blocks_commit now, it will be set after
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment