summaryrefslogtreecommitdiff
path: root/mysql-test
diff options
context:
space:
mode:
authorJon Olav Hauglid <jon.hauglid@sun.com>2010-01-12 16:15:21 +0100
committerJon Olav Hauglid <jon.hauglid@sun.com>2010-01-12 16:15:21 +0100
commitc7bcb28f0c502ad9028712c7c65834c8905ad88f (patch)
treeed8866580b555e7e03ef68459edf2fb58aa0428e /mysql-test
parentbe634ee66e0f6c5d69a174d9a59fa5228211b347 (diff)
downloadmariadb-git-c7bcb28f0c502ad9028712c7c65834c8905ad88f.tar.gz
Bug #49988 MDL deadlocks with mysql_create_db, reload_acl_and_cache
This was a deadlock between LOCK TABLES/CREATE DATABASE in one connection and DROP DATABASE in another. It only happened if the table locked by LOCK TABLES was in the database to be dropped. The deadlock is similar to the one in Bug#48940, but with LOCK TABLES instead of an active transaction. The order of events needed to trigger the deadlock was: 1) Connection 1 locks table db1.t1 using LOCK TABLES. It will now have a metadata lock on the table name. 2) Connection 2 issues DROP DATABASE db1. This will wait inside the MDL subsystem for the lock on db1.t1 to go away. While waiting, it will hold the LOCK_mysql_create_db mutex. 3) Connection 1 issues CREATE DATABASE (database name irrelevant). This will hang trying to lock the same mutex. Since this is the connection holding the metadata lock blocking Connection 2, we have a deadlock. This deadlock would also happen for earlier trees without MDL, but there DROP DATABASE would wait for a table to be removed from the table definition cache. This patch fixes the problem by prohibiting CREATE DATABASE in LOCK TABLES mode. In the example above, this prevents Connection 1 from hanging trying to get the LOCK_mysql_create_db mutex. Note that other commands that use LOCK_mysql_create_db (ALTER/DROP DATABASE) are already prohibited in LOCK TABLES mode. Incompatible change: CREATE DATABASE is now disallowed in LOCK TABLES mode. Test case added to schema.test. mysql-test/t/drop.test: Updates the test for Bug#21216 by swapping the order of CREATE DATABASE and LOCK TABLES. This is now needed as CREATE DATABASE is prohibited in LOCK TABLES mode. mysql-test/t/schema.test: Test case for Bug#49988 added. Also fixes a problem with the test for Bug#48940 where the result would differ for embedded server.
Diffstat (limited to 'mysql-test')
-rw-r--r--mysql-test/r/drop.result2
-rw-r--r--mysql-test/r/schema.result21
-rw-r--r--mysql-test/t/drop.test2
-rw-r--r--mysql-test/t/schema.test45
4 files changed, 66 insertions, 4 deletions
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index 54bd05e526f..8c6bd582232 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -77,8 +77,8 @@ drop table t1;
drop database if exists mysqltest;
drop table if exists t1;
create table t1 (i int);
-lock tables t1 read;
create database mysqltest;
+lock tables t1 read;
drop table t1;
show open tables;
drop database mysqltest;
diff --git a/mysql-test/r/schema.result b/mysql-test/r/schema.result
index 33a2d4d9448..b43f601caef 100644
--- a/mysql-test/r/schema.result
+++ b/mysql-test/r/schema.result
@@ -24,7 +24,26 @@ INSERT INTO schema1.t1 VALUES (1);
DROP SCHEMA schema1;
# Connection default
ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8;
-ERROR HY000: Can't create/write to file './schema1/db.opt' (Errcode: 2)
+Got one of the listed errors
SET autocommit= TRUE;
# Connection 2
# Connection default
+#
+# Bug #49988 MDL deadlocks with mysql_create_db, reload_acl_and_cache
+#
+DROP SCHEMA IF EXISTS schema1;
+# Connection default
+CREATE SCHEMA schema1;
+CREATE TABLE schema1.t1 (id INT);
+LOCK TABLE schema1.t1 WRITE;
+# Connection con2
+DROP SCHEMA schema1;
+# Connection default
+# CREATE SCHEMA used to give a deadlock.
+# Now we prohibit CREATE SCHEMA in LOCK TABLES mode.
+CREATE SCHEMA IF NOT EXISTS schema1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+# UNLOCK TABLES so DROP SCHEMA can continue.
+UNLOCK TABLES;
+# Connection con2
+# Connection default
diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test
index 4aeb7165bcb..5ef4a28b202 100644
--- a/mysql-test/t/drop.test
+++ b/mysql-test/t/drop.test
@@ -100,8 +100,8 @@ drop database if exists mysqltest;
drop table if exists t1;
--enable_warnings
create table t1 (i int);
-lock tables t1 read;
create database mysqltest;
+lock tables t1 read;
connect (addconroot1, localhost, root,,);
--send drop table t1
connect (addconroot2, localhost, root,,);
diff --git a/mysql-test/t/schema.test b/mysql-test/t/schema.test
index a380a6241dd..f106b9e4865 100644
--- a/mysql-test/t/schema.test
+++ b/mysql-test/t/schema.test
@@ -46,7 +46,8 @@ let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
WHERE state= 'Waiting for table'
AND info='DROP SCHEMA schema1';
--source include/wait_condition.inc
---error 1
+# Listing the error twice to prevent result diffences based on filename
+--error 1,1
ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8;
SET autocommit= TRUE;
@@ -59,6 +60,48 @@ connection default;
disconnect con2;
+--echo #
+--echo # Bug #49988 MDL deadlocks with mysql_create_db, reload_acl_and_cache
+--echo #
+
+--disable_warnings
+DROP SCHEMA IF EXISTS schema1;
+--enable_warnings
+
+connect (con2, localhost, root);
+
+--echo # Connection default
+connection default;
+CREATE SCHEMA schema1;
+CREATE TABLE schema1.t1 (id INT);
+LOCK TABLE schema1.t1 WRITE;
+
+--echo # Connection con2
+connection con2;
+--send DROP SCHEMA schema1
+
+--echo # Connection default
+connection default;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' and info='DROP SCHEMA schema1';
+--source include/wait_condition.inc
+
+--echo # CREATE SCHEMA used to give a deadlock.
+--echo # Now we prohibit CREATE SCHEMA in LOCK TABLES mode.
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+CREATE SCHEMA IF NOT EXISTS schema1;
+
+--echo # UNLOCK TABLES so DROP SCHEMA can continue.
+UNLOCK TABLES;
+
+--echo # Connection con2
+connection con2;
+--reap
+
+--echo # Connection default
+connection default;
+disconnect con2;
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc