summaryrefslogtreecommitdiff
path: root/mysql-test/t/schema.test
diff options
context:
space:
mode:
authorJon Olav Hauglid <jon.hauglid@sun.com>2010-07-01 15:53:46 +0200
committerJon Olav Hauglid <jon.hauglid@sun.com>2010-07-01 15:53:46 +0200
commit9ff272fbbd9f8e8bb412cf8ddc12d6e97242ef63 (patch)
treec9d08724cb81d3b7ffd2f6515930d6df9e4b5bf1 /mysql-test/t/schema.test
parent29e9130d60d79b88b9e6593a111ced4363e9225e (diff)
downloadmariadb-git-9ff272fbbd9f8e8bb412cf8ddc12d6e97242ef63.tar.gz
A 5.5 version of the fix for Bug #54360 "Deadlock DROP/ALTER/CREATE
DATABASE with open HANDLER" Remove LOCK_create_db, database name locks, and use metadata locks instead. This exposes CREATE/DROP/ALTER DATABASE statements to the graph-based deadlock detector in MDL, and paves the way for a safe, deadlock-free implementation of RENAME DATABASE. Database DDL statements will now take exclusive metadata locks on the database name, while table/view/routine DDL statements take intention exclusive locks on the database name. This prevents race conditions between database DDL and table/view/routine DDL. (e.g. DROP DATABASE with concurrent CREATE/ALTER/DROP TABLE) By adding database name locks, this patch implements WL#4450 "DDL locking: CREATE/DROP DATABASE must use database locks" and WL#4985 "DDL locking: namespace/hierarchical locks". The patch also changes code to use init_one_table() where appropriate. The new lock_table_names() function requires TABLE_LIST::db_length to be set correctly, and this is taken care of by init_one_table(). This patch also adds a simple template to help work with the mysys HASH data structure. Most of the patch was written by Konstantin Osipov.
Diffstat (limited to 'mysql-test/t/schema.test')
-rw-r--r--mysql-test/t/schema.test98
1 files changed, 95 insertions, 3 deletions
diff --git a/mysql-test/t/schema.test b/mysql-test/t/schema.test
index f106b9e4865..e3592f39780 100644
--- a/mysql-test/t/schema.test
+++ b/mysql-test/t/schema.test
@@ -23,6 +23,7 @@ drop schema foo;
--disable_warnings
DROP SCHEMA IF EXISTS schema1;
+DROP SCHEMA IF EXISTS schema2;
--enable_warnings
connect(con2, localhost, root);
@@ -31,6 +32,7 @@ connect(con2, localhost, root);
connection default;
CREATE SCHEMA schema1;
+CREATE SCHEMA schema2;
CREATE TABLE schema1.t1 (a INT);
SET autocommit= FALSE;
@@ -46,9 +48,7 @@ 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
-# Listing the error twice to prevent result diffences based on filename
---error 1,1
-ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8;
+ALTER SCHEMA schema2 DEFAULT CHARACTER SET utf8;
SET autocommit= TRUE;
--echo # Connection 2
@@ -57,6 +57,7 @@ connection con2;
--echo # Connection default
connection default;
+DROP SCHEMA schema2;
disconnect con2;
@@ -102,6 +103,97 @@ connection con2;
connection default;
disconnect con2;
+
+--echo #
+--echo # Bug#54360 Deadlock DROP/ALTER/CREATE DATABASE with open HANDLER
+--echo #
+
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+INSERT INTO db1.t1 VALUES (1), (2);
+
+--echo # Connection con1
+connect (con1, localhost, root);
+HANDLER db1.t1 OPEN;
+
+--echo # Connection default
+connection default;
+--echo # Sending:
+--send DROP DATABASE db1
+
+--echo # Connection con2
+connect (con2, localhost, root);
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' AND info='DROP DATABASE db1';
+--source include/wait_condition.inc
+
+--echo # Connection con1
+connection con1;
+# All these statements before resulted in deadlock.
+CREATE DATABASE db2;
+ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
+DROP DATABASE db2;
+
+--echo # Connection default
+connection default;
+--echo # Reaping: DROP DATABASE db1
+--reap
+disconnect con1;
+disconnect con2;
+
+
+--echo #
+--echo # Tests for increased CREATE/ALTER/DROP DATABASE concurrency with
+--echo # database name locks.
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+--enable_warnings
+
+connect (con2, localhost, root);
+connect (con3, localhost, root);
+
+--echo # Connection default
+connection default;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (id INT);
+START TRANSACTION;
+INSERT INTO db1.t1 VALUES (1);
+
+--echo # Connection 2
+connection con2;
+--echo # DROP DATABASE should block due to the active transaction
+--echo # Sending:
+--send DROP DATABASE db1
+
+--echo # Connection 3
+connection con3;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' and info='DROP DATABASE db1';
+--source include/wait_condition.inc
+--echo # But it should still be possible to CREATE/ALTER/DROP other databases.
+CREATE DATABASE db2;
+ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
+DROP DATABASE db2;
+
+--echo # Connection default
+connection default;
+--echo # End the transaction so DROP DATABASE db1 can continue
+COMMIT;
+
+--echo # Connection 2
+connection con2;
+--echo # Reaping: DROP DATABASE db1
+--reap
+
+--echo # Connection default;
+connection default;
+disconnect con2;
+disconnect con3;
+
+
# 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