summaryrefslogtreecommitdiff
path: root/mysql-test
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test')
-rw-r--r--mysql-test/r/mdl_sync.result237
-rw-r--r--mysql-test/r/partition_debug_sync.result2
-rw-r--r--mysql-test/r/schema.result50
-rw-r--r--mysql-test/suite/perfschema/r/server_init.result8
-rw-r--r--mysql-test/suite/perfschema/t/server_init.test6
-rw-r--r--mysql-test/t/mdl_sync.test475
-rw-r--r--mysql-test/t/partition_debug_sync.test2
-rw-r--r--mysql-test/t/schema.test98
8 files changed, 857 insertions, 21 deletions
diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result
index 67d778211dd..1b0ffc588e1 100644
--- a/mysql-test/r/mdl_sync.result
+++ b/mysql-test/r/mdl_sync.result
@@ -2527,3 +2527,240 @@ SET DEBUG_SYNC= "now SIGNAL completed";
Field Type Collation Null Key Default Extra Privileges Comment
a char(255) latin1_swedish_ci YES NULL #
DROP TABLE t1;
+#
+# Tests for schema-scope locks
+#
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+# Test 1:
+# CREATE DATABASE blocks database DDL on the same database, but
+# not database DDL on different databases. Tests X vs X lock.
+#
+# Connection default
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+CREATE DATABASE db1;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+CREATE DATABASE db1;
+# Connection con3
+CREATE DATABASE db2;
+ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
+DROP DATABASE db2;
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: CREATE DATABASE db1
+# Connection con2
+# Reaping: CREATE DATABASE db1
+ERROR HY000: Can't create database 'db1'; database exists
+# Test 2:
+# ALTER DATABASE blocks database DDL on the same database, but
+# not database DDL on different databases. Tests X vs X lock.
+#
+# Connection default
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
+# Connection con3
+CREATE DATABASE db2;
+ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
+DROP DATABASE db2;
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+# Connection con2
+# Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+# Connection default
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+DROP DATABASE db1;
+# Connection con3
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+# Connection con2
+# Reaping: DROP DATABASE db1
+CREATE DATABASE db1;
+# Test 3:
+# Two ALTER..UPGRADE of the same database are mutually exclusive, but
+# two ALTER..UPGRADE of different databases are not. Tests X vs X lock.
+#
+# Connection default
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
+# Connection con3
+ALTER DATABASE `#mysql50#a-b-c-d` UPGRADE DATA DIRECTORY NAME;
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
+# Connection con2
+# Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
+ERROR 42000: Unknown database '#mysql50#a-b-c'
+DROP DATABASE `a-b-c`;
+DROP DATABASE `a-b-c-d`;
+# Test 4:
+# DROP DATABASE blocks database DDL on the same database, but
+# not database DDL on different databases. Tests X vs X lock.
+#
+# Connection default
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+DROP DATABASE db1;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+DROP DATABASE db1;
+# Connection con3
+CREATE DATABASE db2;
+ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
+DROP DATABASE db2;
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: DROP DATABASE db1
+# Connection con2
+# Reaping: DROP DATABASE db1
+ERROR HY000: Can't drop database 'db1'; database doesn't exist
+# Connection default
+CREATE DATABASE db1;
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+DROP DATABASE db1;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
+# Connection con3
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: DROP DATABASE db1
+# Connection con2
+# Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+ERROR HY000: Can't create/write to file './db1/db.opt' (Errcode: 2)
+# Test 5:
+# Locked database name prevents CREATE of tables in that database.
+# Tests X vs IX lock.
+#
+# Connection default
+CREATE DATABASE db1;
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+DROP DATABASE db1;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+CREATE TABLE db1.t1 (a INT);
+# Connection con3
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: DROP DATABASE db1
+# Connection con2
+# Reaping: CREATE TABLE db1.t1 (a INT)
+ERROR 42000: Unknown database 'db1'
+# Test 6:
+# Locked database name prevents RENAME of tables to/from that database.
+# Tests X vs IX lock.
+#
+# Connection default
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+DROP DATABASE db1;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+RENAME TABLE db1.t1 TO test.t1;
+# Connection con3
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: DROP DATABASE db1
+# Connection con2
+# Reaping: RENAME TABLE db1.t1 TO test.t1
+ERROR HY000: Can't find file: './db1/t1.frm' (errno: 2)
+# Connection default
+CREATE DATABASE db1;
+CREATE TABLE test.t2 (a INT);
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+DROP DATABASE db1;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+RENAME TABLE test.t2 TO db1.t2;
+# Connection con3
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: DROP DATABASE db1
+# Connection con2
+# Reaping: RENAME TABLE test.t2 TO db1.t2
+ERROR HY000: Error on rename of './test/t2.MYI' to './db1/t2.MYI' (Errcode: 2)
+DROP TABLE test.t2;
+# Test 7:
+# Locked database name prevents DROP of tables in that database.
+# Tests X vs IX lock.
+#
+# Connection default
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+# Sending:
+DROP DATABASE db1;
+# Connection con2
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# Sending:
+DROP TABLE db1.t1;
+# Connection con3
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+# Connection default
+# Reaping: DROP DATABASE db1
+# Connection con2
+# Reaping: DROP TABLE db1.t1
+ERROR 42S02: Unknown table 't1'
+# Connection default
+SET DEBUG_SYNC= 'RESET';
+#
+# End of tests for schema-scope locks
+#
+#
+# Tests of granted global S lock (FLUSH TABLE WITH READ LOCK)
+#
+CREATE DATABASE db1;
+CREATE TABLE db1.t1(a INT);
+# Connection default
+FLUSH TABLE WITH READ LOCK;
+# Connection con2
+CREATE TABLE db1.t2(a INT);
+# Connection default
+UNLOCK TABLES;
+# Connection con2
+# Reaping CREATE TABLE db1.t2(a INT)
+# Connection default
+FLUSH TABLE WITH READ LOCK;
+# Connection con2
+ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
+# Connection default
+UNLOCK TABLES;
+# Connection con2
+# Reaping ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+# Connection default
+FLUSH TABLE WITH READ LOCK;
+# Connection con2
+FLUSH TABLE WITH READ LOCK;
+UNLOCK TABLES;
+# Connection default
+UNLOCK TABLES;
+DROP DATABASE db1;
diff --git a/mysql-test/r/partition_debug_sync.result b/mysql-test/r/partition_debug_sync.result
index 5ab1044934b..0e3241cf88e 100644
--- a/mysql-test/r/partition_debug_sync.result
+++ b/mysql-test/r/partition_debug_sync.result
@@ -47,7 +47,7 @@ ENGINE = MYISAM
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (100),
PARTITION p3 VALUES LESS THAN MAXVALUE ) */;
-SET DEBUG_SYNC= 'open_tables_acquire_upgradable_mdl SIGNAL removing_partitions WAIT_FOR waiting_for_alter';
+SET DEBUG_SYNC= 'alter_table_before_open_tables SIGNAL removing_partitions WAIT_FOR waiting_for_alter';
SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done';
ALTER TABLE t2 REMOVE PARTITIONING;
# Con default
diff --git a/mysql-test/r/schema.result b/mysql-test/r/schema.result
index 2919606d74a..890f53669b5 100644
--- a/mysql-test/r/schema.result
+++ b/mysql-test/r/schema.result
@@ -16,19 +16,21 @@ drop schema foo;
# Bug #48940 MDL deadlocks against mysql_rm_db
#
DROP SCHEMA IF EXISTS schema1;
+DROP SCHEMA IF EXISTS schema2;
# Connection default
CREATE SCHEMA schema1;
+CREATE SCHEMA schema2;
CREATE TABLE schema1.t1 (a INT);
SET autocommit= FALSE;
INSERT INTO schema1.t1 VALUES (1);
# Connection 2
DROP SCHEMA schema1;
# Connection default
-ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8;
-Got one of the listed errors
+ALTER SCHEMA schema2 DEFAULT CHARACTER SET utf8;
SET autocommit= TRUE;
# Connection 2
# Connection default
+DROP SCHEMA schema2;
#
# Bug #49988 MDL deadlocks with mysql_create_db, reload_acl_and_cache
#
@@ -48,3 +50,47 @@ ERROR HY000: Can't execute the given command because you have active locked tabl
UNLOCK TABLES;
# Connection con2
# Connection default
+#
+# Bug#54360 Deadlock DROP/ALTER/CREATE DATABASE with open HANDLER
+#
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+INSERT INTO db1.t1 VALUES (1), (2);
+# Connection con1
+HANDLER db1.t1 OPEN;
+# Connection default
+# Sending:
+DROP DATABASE db1;
+# Connection con2
+# Connection con1
+CREATE DATABASE db2;
+ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
+DROP DATABASE db2;
+# Connection default
+# Reaping: DROP DATABASE db1
+#
+# Tests for increased CREATE/ALTER/DROP DATABASE concurrency with
+# database name locks.
+#
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+# Connection default
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (id INT);
+START TRANSACTION;
+INSERT INTO db1.t1 VALUES (1);
+# Connection 2
+# DROP DATABASE should block due to the active transaction
+# Sending:
+DROP DATABASE db1;
+# Connection 3
+# 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;
+# Connection default
+# End the transaction so DROP DATABASE db1 can continue
+COMMIT;
+# Connection 2
+# Reaping: DROP DATABASE db1
+# Connection default;
diff --git a/mysql-test/suite/perfschema/r/server_init.result b/mysql-test/suite/perfschema/r/server_init.result
index ac340f8eb67..a37a5805dd7 100644
--- a/mysql-test/suite/perfschema/r/server_init.result
+++ b/mysql-test/suite/perfschema/r/server_init.result
@@ -40,18 +40,10 @@ where name like "wait/synch/cond/mysys/THR_COND_threads";
count(name)
1
select count(name) from MUTEX_INSTANCES
-where name like "wait/synch/mutex/sql/LOCK_mysql_create_db";
-count(name)
-1
-select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_open";
count(name)
1
select count(name) from MUTEX_INSTANCES
-where name like "wait/synch/mutex/sql/LOCK_lock_db";
-count(name)
-1
-select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_thread_count";
count(name)
1
diff --git a/mysql-test/suite/perfschema/t/server_init.test b/mysql-test/suite/perfschema/t/server_init.test
index cd9357cce67..0bb3dd84ac4 100644
--- a/mysql-test/suite/perfschema/t/server_init.test
+++ b/mysql-test/suite/perfschema/t/server_init.test
@@ -69,15 +69,9 @@ select count(name) from COND_INSTANCES
# Verify that these global mutexes have been properly initilized in sql
select count(name) from MUTEX_INSTANCES
- where name like "wait/synch/mutex/sql/LOCK_mysql_create_db";
-
-select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_open";
select count(name) from MUTEX_INSTANCES
- where name like "wait/synch/mutex/sql/LOCK_lock_db";
-
-select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_thread_count";
select count(name) from MUTEX_INSTANCES
diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test
index 19f9b396087..441cabb10e2 100644
--- a/mysql-test/t/mdl_sync.test
+++ b/mysql-test/t/mdl_sync.test
@@ -3705,6 +3705,481 @@ DROP TABLE t1;
disconnect con1;
+--echo #
+--echo # Tests for schema-scope 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 # Test 1:
+--echo # CREATE DATABASE blocks database DDL on the same database, but
+--echo # not database DDL on different databases. Tests X vs X lock.
+--echo #
+
+--echo # Connection default
+connection default;
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send CREATE DATABASE db1
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should block.
+--send CREATE DATABASE db1
+
+--echo # Connection con3
+connection con3;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' AND info='CREATE DATABASE db1';
+--source include/wait_condition.inc
+# This should not block.
+CREATE DATABASE db2;
+ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
+DROP DATABASE db2;
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: CREATE DATABASE db1
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: CREATE DATABASE db1
+--error ER_DB_CREATE_EXISTS
+--reap
+
+--echo # Test 2:
+--echo # ALTER DATABASE blocks database DDL on the same database, but
+--echo # not database DDL on different databases. Tests X vs X lock.
+--echo #
+
+--echo # Connection default
+connection default;
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should block.
+--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+
+--echo # Connection con3
+connection con3;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table'
+ AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8';
+--source include/wait_condition.inc
+# This should not block.
+CREATE DATABASE db2;
+ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
+DROP DATABASE db2;
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+--reap
+
+--echo # Connection default
+connection default;
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should also block.
+--send DROP DATABASE db1
+
+--echo # Connection con3
+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
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: DROP DATABASE db1
+--reap
+# Recreate the database
+CREATE DATABASE db1;
+
+--echo # Test 3:
+--echo # Two ALTER..UPGRADE of the same database are mutually exclusive, but
+--echo # two ALTER..UPGRADE of different databases are not. Tests X vs X lock.
+--echo #
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+# Manually make a 5.0 database from the template
+--mkdir $MYSQLD_DATADIR/a-b-c
+--copy_file $MYSQLD_DATADIR/db1/db.opt $MYSQLD_DATADIR/a-b-c/db.opt
+--mkdir $MYSQLD_DATADIR/a-b-c-d
+--copy_file $MYSQLD_DATADIR/db1/db.opt $MYSQLD_DATADIR/a-b-c-d/db.opt
+
+--echo # Connection default
+connection default;
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should block.
+--send ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME
+
+--echo # Connection con3
+connection con3;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table'
+ AND info='ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME';
+--source include/wait_condition.inc
+# This should not block.
+ALTER DATABASE `#mysql50#a-b-c-d` UPGRADE DATA DIRECTORY NAME;
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
+--error ER_BAD_DB_ERROR
+--reap
+DROP DATABASE `a-b-c`;
+DROP DATABASE `a-b-c-d`;
+
+--echo # Test 4:
+--echo # DROP DATABASE blocks database DDL on the same database, but
+--echo # not database DDL on different databases. Tests X vs X lock.
+--echo #
+
+--echo # Connection default
+connection default;
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send DROP DATABASE db1
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should block.
+--send DROP DATABASE db1
+
+--echo # Connection con3
+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
+# This should not block.
+CREATE DATABASE db2;
+ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
+DROP DATABASE db2;
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: DROP DATABASE db1
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: DROP DATABASE db1
+--error ER_DB_DROP_EXISTS
+--reap
+
+--echo # Connection default
+connection default;
+CREATE DATABASE db1;
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send DROP DATABASE db1
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should also block.
+--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+
+--echo # Connection con3
+connection con3;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table'
+ AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8';
+--source include/wait_condition.inc
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: DROP DATABASE db1
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+--error 1 # Wrong error pending followup patch for bug#54360
+--reap
+
+
+--echo # Test 5:
+--echo # Locked database name prevents CREATE of tables in that database.
+--echo # Tests X vs IX lock.
+--echo #
+
+--echo # Connection default
+connection default;
+CREATE DATABASE db1;
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send DROP DATABASE db1
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should block.
+--send CREATE TABLE db1.t1 (a INT)
+
+--echo # Connection con3
+connection con3;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' AND info='CREATE TABLE db1.t1 (a INT)';
+--source include/wait_condition.inc
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: DROP DATABASE db1
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: CREATE TABLE db1.t1 (a INT)
+--error ER_BAD_DB_ERROR
+--reap
+
+--echo # Test 6:
+--echo # Locked database name prevents RENAME of tables to/from that database.
+--echo # Tests X vs IX lock.
+--echo #
+
+--echo # Connection default
+connection default;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send DROP DATABASE db1
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should block.
+--send RENAME TABLE db1.t1 TO test.t1
+
+--echo # Connection con3
+connection con3;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' AND info='RENAME TABLE db1.t1 TO test.t1';
+--source include/wait_condition.inc
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: DROP DATABASE db1
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: RENAME TABLE db1.t1 TO test.t1
+--error ER_FILE_NOT_FOUND
+--reap
+
+--echo # Connection default
+connection default;
+CREATE DATABASE db1;
+CREATE TABLE test.t2 (a INT);
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send DROP DATABASE db1
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should block.
+--send RENAME TABLE test.t2 TO db1.t2
+
+--echo # Connection con3
+connection con3;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' AND info='RENAME TABLE test.t2 TO db1.t2';
+--source include/wait_condition.inc
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: DROP DATABASE db1
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: RENAME TABLE test.t2 TO db1.t2
+--error 7 # Wrong error pending followup patch for bug#54360
+--reap
+DROP TABLE test.t2;
+
+
+--echo # Test 7:
+--echo # Locked database name prevents DROP of tables in that database.
+--echo # Tests X vs IX lock.
+--echo #
+
+--echo # Connection default
+connection default;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
+--echo # Sending:
+--send DROP DATABASE db1
+
+--echo # Connection con2
+connection con2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--echo # Sending:
+# This should block.
+--send DROP TABLE db1.t1
+
+--echo # Connection con3
+connection con3;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for table' AND info='DROP TABLE db1.t1';
+--source include/wait_condition.inc
+SET DEBUG_SYNC= 'now SIGNAL blocked';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: DROP DATABASE db1
+--reap
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping: DROP TABLE db1.t1
+--error ER_BAD_TABLE_ERROR
+--reap
+
+--echo # Connection default
+connection default;
+disconnect con2;
+disconnect con3;
+SET DEBUG_SYNC= 'RESET';
+
+--echo #
+--echo # End of tests for schema-scope locks
+--echo #
+
+--echo #
+--echo # Tests of granted global S lock (FLUSH TABLE WITH READ LOCK)
+--echo #
+
+CREATE DATABASE db1;
+CREATE TABLE db1.t1(a INT);
+connect(con2, localhost, root);
+connect(con3, localhost, root);
+
+--echo # Connection default
+connection default;
+FLUSH TABLE WITH READ LOCK;
+
+--echo # Connection con2
+connection con2;
+# IX global lock should block
+--send CREATE TABLE db1.t2(a INT)
+
+--echo # Connection default
+connection default;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for release of readlock'
+ AND info='CREATE TABLE db1.t2(a INT)';
+--source include/wait_condition.inc
+UNLOCK TABLES;
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping CREATE TABLE db1.t2(a INT)
+--reap
+
+--echo # Connection default
+connection default;
+FLUSH TABLE WITH READ LOCK;
+
+--echo # Connection con2
+connection con2;
+# X global lock should block
+--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+
+--echo # Connection default
+connection default;
+let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
+ WHERE state='Waiting for release of readlock'
+ AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8';
+--source include/wait_condition.inc
+UNLOCK TABLES;
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
+--reap
+
+--echo # Connection default
+connection default;
+FLUSH TABLE WITH READ LOCK;
+
+--echo # Connection con2
+connection con2;
+# S global lock should not block
+FLUSH TABLE WITH READ LOCK;
+UNLOCK TABLES;
+
+--echo # Connection default
+connection default;
+UNLOCK TABLES;
+DROP DATABASE db1;
+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
diff --git a/mysql-test/t/partition_debug_sync.test b/mysql-test/t/partition_debug_sync.test
index 9165006f537..cde94856ae6 100644
--- a/mysql-test/t/partition_debug_sync.test
+++ b/mysql-test/t/partition_debug_sync.test
@@ -65,7 +65,7 @@ ENGINE = MYISAM
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (100),
PARTITION p3 VALUES LESS THAN MAXVALUE ) */;
-SET DEBUG_SYNC= 'open_tables_acquire_upgradable_mdl SIGNAL removing_partitions WAIT_FOR waiting_for_alter';
+SET DEBUG_SYNC= 'alter_table_before_open_tables SIGNAL removing_partitions WAIT_FOR waiting_for_alter';
SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done';
--send ALTER TABLE t2 REMOVE PARTITIONING
connection default;
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