polardbxengine/mysql-test/t/schema.test

699 lines
19 KiB
Plaintext

#
# Just a couple of tests to make sure that schema works.
#
# Drop mysqltest1 database, as it can left from the previous tests.
#
--source include/have_debug_sync.inc
# Save the initial number of concurrent sessions.
--source include/count_sessions.inc
let $MYSQLD_DATADIR= `SELECT @@datadir`;
# MDL blocking concurrent drop schema is different with --ps-protocol
let $drop_schema_target_state='Waiting for schema metadata lock';
if (`SELECT $PS_PROTOCOL = 1`)
{
let $drop_schema_target_state='Waiting for table metadata lock';
}
--disable_warnings
drop database if exists mysqltest1;
--enable_warnings
create schema foo;
show create schema foo;
show schemas like 'foo';
drop schema foo;
--echo #
--echo # Bug #48940 MDL deadlocks against mysql_rm_db
--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 (a INT);
SET autocommit= FALSE;
INSERT INTO schema1.t1 VALUES (1);
--echo # Connection 2
connection con2;
--send DROP SCHEMA schema1
--echo # Connection default
connection default;
let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
WHERE state= $drop_schema_target_state
AND info='DROP SCHEMA schema1';
--source include/wait_condition.inc
--error ER_NO_SUCH_DB
ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8;
SET autocommit= TRUE;
--echo # Connection 2
connection con2;
--reap
--echo # Connection default
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 schema metadata lock' 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;
--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 metadata lock' 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;
HANDLER t1 CLOSE;
--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= $drop_schema_target_state;
--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;
--enable_connect_log
--echo #
--echo # Bug#21305766: DML ON A NON EXISTING TABLE DOES NOT ACQUIRE MDL ON THE SCHEMA NAME
--echo #
--echo # Set lock_wait_timeout, create a schema and a connection con1.
SET @start_session_value= @@session.lock_wait_timeout;
SET @@session.lock_wait_timeout= 1;
CREATE SCHEMA testdb;
--connect(con1, localhost, root)
--echo # Access a non-existing table in the created schema, and park it after
--echo # acquiring the schema while acquiring the dd::Table object.
SET DEBUG_SYNC= 'acquired_schema_while_acquiring_table SIGNAL acquired WAIT_FOR cont';
--send SELECT * from testdb.no_such_table
--connection default
--echo # From the default connection, drop the schema, then resume
--echo # con1. Without the patch in the server code, DROP SCHEMA
--echo # will fail with an assert due to the schema object being
--echo # acquired by more than one thread. With the patch, we get
--echo # a lock wait timeout for DROP since the other thread has an
--echo # IX-lock on the schema name.
SET DEBUG_SYNC= 'now WAIT_FOR acquired';
--error ER_LOCK_WAIT_TIMEOUT
DROP SCHEMA testdb;
SET DEBUG_SYNC= 'now SIGNAL cont';
--connection con1
--echo # Reaping SELECT * from testdb.no_such_table
--error ER_NO_SUCH_TABLE
--reap
--disconnect con1
--source include/wait_until_disconnected.inc
--connection default
--echo # Drop testdb and reset
DROP SCHEMA testdb;
SET @@session.lock_wait_timeout= @start_session_value;
SET DEBUG_SYNC= 'RESET';
--disable_connect_log
--echo #
--echo # Bug #21837759: SYNCHRONIZE USAGE OF SCHEMA DD OBJECTS BY MDL ACQUISITION
--echo #
--echo # Do a 'USE <schema>' and park it after retrieving the schema for
--echo # finding the default db collation. Then, from a different
--echo # connection, drop the same schema. Without the bugfix, this
--echo # will fail due to improper concurrent usage of the DD cache
--echo # elements. With the bugfix, the DROP will fail with a lock
--echo # wait timeout due to the operations now being properly synchronized
--echo # by meta data locking.
--enable_connect_log
--echo #
--echo # Create the schema to be used in the test.
SET @start_session_value= @@session.lock_wait_timeout;
SET @@session.lock_wait_timeout= 1;
CREATE SCHEMA testdb;
--echo #
--echo # Create a new connection, change schema, and stop after
--echo # retrieving the schema object for finding the default
--echo # collation.
--connect (con1, localhost, root)
SET DEBUG_SYNC= 'acquired_schema_while_getting_collation SIGNAL acquired WAIT_FOR cont';
--send USE testdb
--echo #
--echo # On the default connection, do a DROP schema while the
--echo # other connection is holding the same schema object.
--echo # This will fail with a lock wait timeout when the operations
--echo # are properly synched by MDL. Without the synchronization,
--echo # this will trigger an assert in the shared DD cache.
--connection default
SET DEBUG_SYNC= 'now WAIT_FOR acquired';
--error ER_LOCK_WAIT_TIMEOUT
DROP SCHEMA testdb;
SET DEBUG_SYNC= 'now SIGNAL cont';
--echo #
--echo # Reap, reset, and delete connection.
--connection con1
--reap
--disconnect con1
--source include/wait_until_disconnected.inc
--connection default
SET DEBUG_SYNC= 'RESET';
DROP SCHEMA testdb;
SET @@session.lock_wait_timeout= @start_session_value;
--disable_connect_log
# 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
#
# WL#6378: New data dictionary.
#
# Replace usage of 'check_db_dir_existence()' by
# 'dd::schema_exists()'. Error handling will be
# slightly different in some situations. Below,
# six test cases check the behavior.
--disable_query_log
CALL mtr.add_suppression("Failed to find tablespace");
CALL mtr.add_suppression("Ignoring tablespace");
CALL mtr.add_suppression("Cannot rename");
CALL mtr.add_suppression("Cannot calculate");
CALL mtr.add_suppression("Cannot open datafile");
CALL mtr.add_suppression("The error means the system cannot find");
CALL mtr.add_suppression("File ./s/t_innodb.ibd");
CALL mtr.add_suppression("Operating system error number");
--enable_query_log
# 1. Create schema, remove directory, then try schema statements.
# Schema directory path.
--let $MYSQL_DATA_DIR= `select @@datadir`
--let $SCHEMA_DIR= $MYSQL_DATA_DIR/s
# Create and remove schema directory.
CREATE SCHEMA s;
--rmdir $SCHEMA_DIR
# SHOW CREATE SCHEMA accesses meta data only, and succeeds.
SHOW CREATE SCHEMA s;
# USE SCHEMA checks meta data only, and succeeds
USE s;
# ALTER SCHEMA is a meta data only operation, and succeeds.
ALTER SCHEMA s DEFAULT COLLATE= utf8_general_ci;
# SHOW CREATE SCHEMA accesses meta data only, and succeeds.
SHOW CREATE SCHEMA s;
# DROP SCHEMA verifies directory existence, and fails.
--replace_result $MYSQLD_DATADIR ./ \\ /
--error ER_SCHEMA_DIR_MISSING
DROP SCHEMA s;
# Re-create the directory, then DROP will work.
--mkdir $SCHEMA_DIR
DROP SCHEMA s;
# 2. Create schema, remove directory, then try CREATE VIEW.
# Schema directory path.
--let $MYSQL_DATA_DIR= `select @@datadir`
--let $SCHEMA_DIR= $MYSQL_DATA_DIR/s
# Create and remove schema directory.
CREATE SCHEMA s;
--rmdir $SCHEMA_DIR
# CREATE VIEW does not access the file system, and succeeds.
CREATE VIEW s.v AS SELECT * FROM mysql.time_zone;
# Re-create the directory, then DROP will work.
--mkdir $SCHEMA_DIR
DROP SCHEMA s;
# 3. Create schema, remove directory, then try CREATE TABLE.
# Schema directory path.
--let $MYSQL_DATA_DIR= `select @@datadir`
--let $SCHEMA_DIR= $MYSQL_DATA_DIR/s
# Create and remove schema directory.
CREATE SCHEMA s;
--rmdir $SCHEMA_DIR
# CREATE TABLE for InnoDB creates parent directory, and succeeds.
CREATE TABLE s.t (pk INTEGER PRIMARY KEY) ENGINE= InnoDB;
--list_files $SCHEMA_DIR
# DROP will work here since InnoDB created the directory.
DROP SCHEMA s;
# 4. Create schema, create tables, remove directory, then try ALTER TABLE.
# Schema directory path.
--let $MYSQL_DATA_DIR= `select @@datadir`
--let $SCHEMA_DIR= $MYSQL_DATA_DIR/s
# CREATE SCHEMA.
CREATE SCHEMA s;
# CREATE TABLE for InnoDB.
CREATE TABLE s.t_innodb (pk INTEGER PRIMARY KEY) ENGINE= InnoDB;
# Shut server down.
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
--source include/wait_until_disconnected.inc
# Remove schema directory and files.
--remove_files_wildcard $SCHEMA_DIR *
--rmdir $SCHEMA_DIR
# Restart the server.
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
# ALTER TABLE for InnoDB fails differently depending on platform.
--error ER_GET_ERRNO, ER_TABLESPACE_MISSING
ALTER TABLE s.t_innodb ADD COLUMN c INTEGER;
# Re-create the directory, then DROP will work.
--mkdir $SCHEMA_DIR
DROP SCHEMA s;
# 5. Create schema, create tables, remove directory, then try SHOW CREATE TABLE.
# Schema directory path.
--let $MYSQL_DATA_DIR= `select @@datadir`
--let $SCHEMA_DIR= $MYSQL_DATA_DIR/s
# CREATE SCHEMA.
CREATE SCHEMA s;
# CREATE TABLE for InnoDB.
CREATE TABLE s.t_innodb (pk INTEGER PRIMARY KEY) ENGINE= InnoDB;
# Shut server down.
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
--source include/wait_until_disconnected.inc
# Remove schema directory and files.
--remove_files_wildcard $SCHEMA_DIR *
--rmdir $SCHEMA_DIR
# Restart the server.
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
# SHOW CREATE TABLE for InnoDB succeeds except on Windows.
# Mute the statement due to platform dependent output.
--disable_query_log
--error 0, ER_TABLESPACE_MISSING
SHOW CREATE TABLE s.t_innodb;
--enable_query_log
# Re-create the directory, then DROP will work.
--mkdir $SCHEMA_DIR
DROP SCHEMA s;
# 6. Create schema, create tables, remove directory, then try DROP TABLE.
# Schema directory path.
--let $MYSQL_DATA_DIR= `select @@datadir`
--let $SCHEMA_DIR= $MYSQL_DATA_DIR/s
# CREATE SCHEMA.
CREATE SCHEMA s;
# CREATE TABLE for InnoDB.
CREATE TABLE s.t_innodb (pk INTEGER PRIMARY KEY) ENGINE= InnoDB;
# Shut server down.
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server
--source include/wait_until_disconnected.inc
# Remove schema directory and files.
--remove_files_wildcard $SCHEMA_DIR *
--rmdir $SCHEMA_DIR
# Restart the server.
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc
# DROP TABLE for InnoDB succeeds.
DROP TABLE s.t_innodb;
# Re-create the directory, then DROP will work.
--mkdir $SCHEMA_DIR
DROP SCHEMA s;
# End of tests for WL#6378: New data dictionary.
--echo #
--echo # Bug#24732194: "USE DB_NAME" AND "SELECT SCHEMA()"
--echo # WORK FOR NON-EXISTING DATABASES
--echo #
# Create the directory manually
--mkdir $SCHEMA_DIR
# USE should fail, it didn't before.
--error ER_BAD_DB_ERROR
USE s;
# Cleanup
--rmdir $SCHEMA_DIR
--echo #
--echo # WL#7743 "New data dictionary: changes to DDL-related parts of SE API"
--echo #
--echo # Additional test coverage for changes in DROP DATABASE implementation.
--echo # Check what happens when we fail to remove database directory during
--echo # the last step of DROP DATABASE, when statement is already committed.
--enable_connect_log
--disable_query_log
CALL mtr.add_suppression("Problem while dropping database. Can't remove database directory .* Please remove it manually.");
--enable_query_log
let $MYSQLD_DATADIR= `SELECT @@datadir`;
CREATE DATABASE db1;
CREATE FUNCTION db1.f1() RETURNS INT RETURN 0;
connect (con1, localhost, root,,);
--echo # Acquire S lock on db1.f1(), so upcoming DROP DATABASE will get
--echo # blocked.
BEGIN;
SELECT db1.f1();
connection default;
--echo # Send:
--send DROP DATABASE db1
connection con1;
--echo # Wait until the above DROP DATABASE is blocked because of S lock.
let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
WHERE state= 'Waiting for stored function metadata lock'
AND info='DROP DATABASE db1';
--source include/wait_condition.inc
--echo # Replace database directory with an empty file.
--rmdir $MYSQLD_DATADIR/db1
--write_file $MYSQLD_DATADIR/db1
EOF
--echo # Unblock DROP DATABASE by releasing S lock.
COMMIT;
disconnect con1;
--source include/wait_until_disconnected.inc
connection default;
--echo # Reap DROP DATABASE. Statement should succeed, but send warnings
--echo # about problems with removing database directory to user ...
--replace_result $MYSQLD_DATADIR ./ \\ /
--replace_regex /errno: [0-9]+ - .*\)/errno: ## - ...)/
--reap
--echo # ... and error log too. Let's check that.
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
--let SEARCH_PATTERN= Problem while dropping database. Can't remove database directory .* Please remove it manually.
--source include/search_pattern.inc
--echo # Clean-up.
--remove_file $MYSQLD_DATADIR/db1
--disable_connect_log
--echo #
--echo # Bug#24510948: ALTER TABLE+INSERT+DROP DB HANG
--echo #
CREATE DATABASE db1;
CREATE TABLE db1.t1(id INT, title VARCHAR(100),
FULLTEXT fidx(title), PRIMARY KEY(id));
--echo # Con1 will attempt insert and block holding open_in_progress on share
--connect(con1, localhost, root)
SET DEBUG_SYNC= 'get_share_before_open SIGNAL wait_share WAIT_FOR continue_insert';
SET SESSION lock_wait_timeout= 5;
--send INSERT INTO db1.t1 VALUES(1, 'mysql database')
--echo # Con2 will attempt alter and block before waiting on COND_open
--connect(con2, localhost, root)
SET DEBUG_SYNC= 'now WAIT_FOR wait_share';
SET DEBUG_SYNC= 'get_share_before_COND_open_wait SIGNAL wait_cond WAIT_FOR continue_alter';
--send ALTER TABLE db1.t1 DROP INDEX fidx
--echo # Con3 will wait until the other connections are waiting for signals,
--echo # then attempt to drop schema, which requires X-MDL
--connect(con3, localhost, root)
SET DEBUG_SYNC= 'now WAIT_FOR wait_cond';
--send DROP DATABASE db1
--connection default
let $wait_condition=
SELECT COUNT(*) = 1 FROM information_schema.processlist
WHERE state = "Waiting for schema metadata lock" AND
info = "DROP DATABASE db1";
--source include/wait_condition.inc
--echo # Con3 is now waiting for MDL on schema. Waking the other connections
--echo # should let them continue (before fix con1 and con2 would deadlock
--echo # on schema MDL and LOCK_open (protecting share->open_in_progress)
--echo # until con1 aborts with lock timeout
SET DEBUG_SYNC= 'now SIGNAL continue_insert';
SET DEBUG_SYNC= 'now SIGNAL continue_alter';
--echo # Reaping connection con1
--connection con1
--reap
--echo # Reaping connection con2
--connection con2
--reap
--echo # Reaping connection con3
--connection con3
--reap
--disable_query_log
call mtr.add_suppression("\\[Warning\\] .*MY-\\d+.* Tablespace .*, name '.*', file '.*' is missing!");
--enable_query_log
--echo #
--echo # Bug#26043994: CREATE DATABASE/DIRECTORY INCONSISTENCY
--echo #
--echo # Dropping a non-existing schema fails
--error ER_DB_DROP_EXISTS
DROP SCHEMA s1;
--echo # but drop succeeds (with a warning) when using IF EXISTS
DROP SCHEMA IF EXISTS s1;
--echo # Verify that schema can be created successfully
CREATE SCHEMA s1;
--echo # Verify that trying to create it again fails
--error ER_DB_CREATE_EXISTS
CREATE SCHEMA s1;
--echo # but create succeds (with a warning) when using IF NOT EXITSTS
CREATE SCHEMA IF NOT EXISTS s1;
DROP SCHEMA s1;
--echo # Create a directory in datadir manually
--mkdir $MYSQLD_DATADIR/bogus__
--echo # Creating a schema with the same name as directory in datadir fails
--echo # but with new error message
--replace_result $MYSQLD_DATADIR ./ \\ /
--error ER_SCHEMA_DIR_EXISTS
CREATE SCHEMA bogus__;
--echo # Creating a schema with the same name as a directory in datadir
--echo # with IF NOT EXISTS fails.
--replace_result $MYSQLD_DATADIR ./ \\ /
--error ER_SCHEMA_DIR_EXISTS
CREATE SCHEMA IF NOT EXISTS bogus__;
--echo # Drop a non-existent schema with the same name as a directory in
--echo # datadir fails.
--replace_result $MYSQLD_DATADIR ./ \\ /
--error ER_SCHEMA_DIR_UNKNOWN
DROP SCHEMA bogus__;
--echo # Drop a non-existent schema with the same name as a directory in
--echo # datadir with IF EXISTS fails.
--replace_result $MYSQLD_DATADIR ./ \\ /
--error ER_SCHEMA_DIR_UNKNOWN
DROP SCHEMA IF EXISTS bogus__;
--rmdir $MYSQLD_DATADIR/bogus__
CREATE SCHEMA broken;
--echo # Remove the schema directory for an existing schema
--rmdir $MYSQLD_DATADIR/broken
--echo # Drop then fails with new error message
--replace_result $MYSQLD_DATADIR ./ \\ /
--error ER_SCHEMA_DIR_MISSING
DROP SCHEMA broken;
--echo # but drop succeeds (with warning) when adding IF EXISTS
--echo # Suppress output since it is not stable across platforms
--disable_warnings ER_SCHEMA_DIR_MISSING ONCE
DROP SCHEMA IF EXISTS broken;
--echo # Create and drop schema again to make sure nothing is left behind
CREATE SCHEMA broken;
DROP SCHEMA broken;