set tidb_cost_model_version=1; # # Tests for various concurrency-related aspects of ALTER TABLE implemetation # # This test takes rather long time so let us run it only in --big-test mode --source include/big_test.inc # We are using some debug-only features in this test --source include/have_debug.inc # Also we are using SBR to check that statements are executed # in proper order. --source include/force_binlog_format_statement.inc --source include/count_sessions.inc # # Additional coverage for the main ALTER TABLE case # # We should be sure that table being altered is properly # locked during statement execution and in particular that # no DDL or DML statement can sneak in and get access to # the table when real operation has already taken place # but this fact has not been noted in binary log yet. # --disable_warnings # drop table if exists t1, t2, t3; # --enable_warnings # connect (addconroot, localhost, root,,); # connect (addconroot2, localhost, root,,); # connection default; # create table t1 (i int); # We are going to check that statements are logged in correct order #reset master; # set debug_sync='alter_table_before_main_binlog SIGNAL parked WAIT_FOR go'; # --send alter table t1 change i c char(10) default 'Test1'; # connection addconroot; # Wait until ALTER TABLE acquires metadata lock. # set debug_sync='now WAIT_FOR parked'; # --send insert into t1 values (); # connection addconroot2; # Wait until the above INSERT INTO t1 is blocked due to ALTER # let $wait_condition= # select count(*) = 1 from information_schema.processlist # where state = "Waiting for table metadata lock" and # info = "insert into t1 values ()"; # --source include/wait_condition.inc # Resume ALTER execution. # set debug_sync='now SIGNAL go'; # connection default; # --reap # connection addconroot; # --reap # connection default; # select * from t1; # set debug_sync='alter_table_before_main_binlog SIGNAL parked WAIT_FOR go'; # --send alter table t1 change c vc varchar(100) default 'Test2'; # connection addconroot; # Wait until ALTER TABLE acquires metadata lock. # set debug_sync='now WAIT_FOR parked'; #--send rename table t1 to t2; # connection addconroot2; # Wait until the above RENAME TABLE is blocked due to ALTER # let $wait_condition= # select count(*) = 1 from information_schema.processlist # where state = "Waiting for table metadata lock" and # info = "rename table t1 to t2"; # --source include/wait_condition.inc # Resume ALTER execution. # set debug_sync='now SIGNAL go'; # connection default; # --reap # connection addconroot; # --reap # connection default; # drop table t2; # And now tests for ALTER TABLE with RENAME clause. In this # case target table name should be properly locked as well. # create table t1 (i int); # set debug_sync='alter_table_before_main_binlog SIGNAL parked WAIT_FOR go'; # --send alter table t1 change i c char(10) default 'Test3', rename to t2; # connection addconroot; # Wait until ALTER TABLE acquires metadata lock. # set debug_sync='now WAIT_FOR parked'; # --send insert into t2 values(); # connection addconroot2; # Wait until the above INSERT INTO t2 is blocked due to ALTER # let $wait_condition= # select count(*) = 1 from information_schema.processlist # where state = "Waiting for table metadata lock" and # info = "insert into t2 values()"; # --source include/wait_condition.inc # Resume ALTER execution. # set debug_sync='now SIGNAL go'; # connection default; # --reap # connection addconroot; # --reap # connection default; # select * from t2; # --send alter table t2 change c vc varchar(100) default 'Test2', rename to t1; # connection addconroot; # connection default; # --reap # rename table t1 to t3; # disconnect addconroot; # disconnect addconroot2; # drop table t3; # set debug_sync='alter_table_before_main_binlog SIGNAL parked WAIT_FOR go'; # set debug_sync='RESET'; # Check that all statements were logged in correct order # source include/show_binlog_events.inc; #--echo End of 5.1 tests #--source include/restore_default_binlog_format.inc --echo # --echo # Additional coverage for WL#7743 "New data dictionary: changes --echo # to DDL-related parts of SE API". --echo # --echo # Killed ALTER TABLE on temporary table sometimes led to assertion --echo # failure on connection close. --enable_connect_log --connect (con1, localhost, root,,alter_table-big) create temporary table t1 (i int) engine=innodb; set debug= "+d,mysql_lock_tables_kill_query"; --error ER_QUERY_INTERRUPTED alter table t1 add index (i); set debug= "-d,mysql_lock_tables_kill_query"; --echo # The below disconnect should drop temporary table automagically. --disconnect con1 --source include/wait_until_disconnected.inc connection default; --disable_connect_log --echo # --echo # Test coverage for new (since 8.0) behavior of ALTER TABLE RENAME --echo # under LOCK TABLES. --echo # --enable_connect_log connect (con1, localhost, root,,); SET @old_lock_wait_timeout= @@lock_wait_timeout; connection default; --echo # --echo # 1) Simple ALTER TABLE RENAME. --echo # --echo # 1.1) Successfull ALTER TABLE RENAME. --echo # CREATE TABLE t1 (i INT); LOCK TABLES t1 WRITE; ALTER TABLE t1 RENAME TO t2; --echo # Table is available under new name under LOCK TABLES. SELECT * FROM t2; connection con1; --echo # Access by new name from other connections should be blocked. SET @@lock_wait_timeout= 1; --error ER_LOCK_WAIT_TIMEOUT SELECT * FROM t2; SET @@lock_wait_timeout= @old_lock_wait_timeout; --echo # But not for old table name. --error ER_NO_SUCH_TABLE SELECT * FROM t1; connection default; UNLOCK TABLES; --echo # --echo # 1.2) ALTER TABLE RENAME in case when several tables are locked. --echo # CREATE TABLE t1 (i INT); LOCK TABLES t1 READ, t2 WRITE; ALTER TABLE t2 RENAME TO t3; --echo # Table t1 should be still locked, and t2 should be available as t3 --echo # with correct lock type. SELECT * FROM t1; INSERT INTO t3 values (1); UNLOCK TABLES; # --echo # # --echo # 1.3) ALTER TABLE RENAME in case when same table locked more than once. # --echo # # LOCK TABLES t1 READ, t3 WRITE, t3 AS a WRITE, t3 AS b READ; # ALTER TABLE t3 RENAME TO t4; # --echo # Check that tables are locked under correct aliases and with modes. # SELECT * FROM t4 AS a, t4 AS b; # INSERT INTO t4 VALUES (2); # DELETE a FROM t4 AS a, t4 AS b; # --error ER_TABLE_NOT_LOCKED_FOR_WRITE # DELETE b FROM t4 AS a, t4 AS b; # UNLOCK TABLES; # DROP TABLES t1, t4; # --echo # 1.4) ALTER TABLE RENAME to different schema. # --echo # DROP TABLES IF EXISTS t1,t3; # CREATE TABLE t1 (i INT); # CREATE DATABASE mysqltest; # LOCK TABLES t1 WRITE; # ALTER TABLE t1 RENAME TO mysqltest.t1; # --echo # Table is available in new schema under LOCK TABLES. # SELECT * FROM mysqltest.t1; # connection con1; # --echo # Access by new name from other connections should be blocked. # SET @@lock_wait_timeout= 1; # --error ER_LOCK_WAIT_TIMEOUT # SELECT * FROM mysqltest.t1; # SET @@lock_wait_timeout= @old_lock_wait_timeout; # --echo # But not to old schema and table name. # --error ER_NO_SUCH_TABLE # SELECT * FROM t1; # --echo # Also IX lock on new schema should be kept. # SET @@lock_wait_timeout= 1; # --error ER_LOCK_WAIT_TIMEOUT # ALTER DATABASE mysqltest CHARACTER SET latin1; # SET @@lock_wait_timeout= @old_lock_wait_timeout; # connection default; # UNLOCK TABLES; # DROP DATABASE mysqltest; --echo # --echo # 2) ALTER TABLE INPLACE with RENAME clause. --echo # --echo # 2.1) Successful ALTER TABLE INPLACE with RENAME clause. --echo # CREATE TABLE t1 (i INT); LOCK TABLES t1 WRITE; ALTER TABLE t1 ADD COLUMN j INT; ALTER TABLE t1 RENAME TO t2, ALGORITHM=INPLACE; --echo # Table is available under new name under LOCK TABLES. SELECT * FROM t2; connection con1; --echo # Access by new name from other connections should be blocked. SET @@lock_wait_timeout= 1; --error ER_LOCK_WAIT_TIMEOUT SELECT * FROM t2; SET @@lock_wait_timeout= @old_lock_wait_timeout; --echo # But not for old table name. --error ER_NO_SUCH_TABLE SELECT * FROM t1; connection default; UNLOCK TABLES; # --echo # # --echo # 2.2) ALTER TABLE INPLACE with RENAME clause in case when several # --echo # tables are locked. # --echo # # CREATE TABLE t1 (i INT); # LOCK TABLES t1 READ, t2 WRITE; # ALTER TABLE t2 ADD COLUMN k INT; # ALTER TABLE t2 RENAME TO t3, ALGORITHM=INPLACE; # --echo # Table t1 should be still locked, and t2 should be available as t3 # --echo # with correct lock type. # SELECT * FROM t1; # INSERT INTO t3 values (1, 2, 3); # UNLOCK TABLES; # --echo # # --echo # 2.3) ALTER TABLE INPLACE with RENAME clause in case when same table # --echo # locked more than once. # --echo # # LOCK TABLES t1 READ, t3 WRITE, t3 AS a WRITE, t3 AS b READ; # ALTER TABLE t3 ADD COLUMN l INT; # ALTER TABLE t3 RENAME TO t4, ALGORITHM=INPLACE; # --echo # Check that tables are locked under correct aliases and with modes. # SELECT * FROM t4 AS a, t4 AS b; # INSERT INTO t4 VALUES (2, 3, 4, 5); # DELETE a FROM t4 AS a, t4 AS b; # --error ER_TABLE_NOT_LOCKED_FOR_WRITE # DELETE b FROM t4 AS a, t4 AS b; # UNLOCK TABLES; # DROP TABLES t1, t4; # --echo # 2.4) ALTER TABLE INPLACE with RENAME clause to different schema. # --echo # # CREATE TABLE t1 (i INT); # CREATE DATABASE mysqltest; # LOCK TABLES t1 WRITE; # ALTER TABLE t1 ADD COLUMN k INT; # ALTER TABLE t1 RENAME TO mysqltest.t1, ALGORITHM=INPLACE; # --echo # Table is available in new schema under LOCK TABLES. # SELECT * FROM mysqltest.t1; # connection con1; # --echo # Access by new name from other connections should be blocked. # SET @@lock_wait_timeout= 1; # --error ER_LOCK_WAIT_TIMEOUT # SELECT * FROM mysqltest.t1; # SET @@lock_wait_timeout= @old_lock_wait_timeout; # --echo # But not to old schema and table name. # --error ER_NO_SUCH_TABLE # SELECT * FROM t1; # --echo # Also IX lock on new schema should be kept. # SET @@lock_wait_timeout= 1; # --error ER_LOCK_WAIT_TIMEOUT # ALTER DATABASE mysqltest CHARACTER SET latin1; # SET @@lock_wait_timeout= @old_lock_wait_timeout; # connection default; # UNLOCK TABLES; # DROP DATABASE mysqltest; --echo # --echo # 3) ALTER TABLE COPY with RENAME clause. --echo # --echo # 3.1) Successful ALTER TABLE COPY with RENAME clause. --echo # DROP TABLES t2; CREATE TABLE t1 (i INT); LOCK TABLES t1 WRITE; ALTER TABLE t1 ADD COLUMN j INT; ALTER TABLE t1 RENAME TO t2, ALGORITHM=COPY; --echo # Table is available under new name under LOCK TABLES. SELECT * FROM t2; connection con1; --echo # Access by new name from other connections should be blocked. SET @@lock_wait_timeout= 1; --error ER_LOCK_WAIT_TIMEOUT SELECT * FROM t2; SET @@lock_wait_timeout= @old_lock_wait_timeout; --echo # But not for old table name. --error ER_NO_SUCH_TABLE SELECT * FROM t1; connection default; UNLOCK TABLES; --echo # --echo # 3.2) ALTER TABLE COPY with RENAME clause in case when several --echo # tables are locked. --echo # CREATE TABLE t1 (i INT); LOCK TABLES t1 READ, t2 WRITE; ALTER TABLE t2 ADD COLUMN k INT; ALTER TABLE t2 RENAME TO t3, ALGORITHM=COPY; --echo # Table t1 should be still locked, and t2 should be available as t3 --echo # with correct lock type. SELECT * FROM t1; INSERT INTO t3 values (1, 2, 3); UNLOCK TABLES; # --echo # # --echo # 3.3) ALTER TABLE COPY with RENAME clause in case when same table # --echo # locked more than once. # --echo # # LOCK TABLES t1 READ, t3 WRITE, t3 AS a WRITE, t3 AS b READ; # ALTER TABLE t3 ADD COLUMN l INT; # ALTER TABLE t3 ADD RENAME TO t4, ALGORITHM=COPY; # --echo # Check that tables are locked under correct aliases and with modes. # SELECT * FROM t4 AS a, t4 AS b; # INSERT INTO t4 VALUES (2, 3, 4, 5); # DELETE a FROM t4 AS a, t4 AS b; # --error ER_TABLE_NOT_LOCKED_FOR_WRITE # DELETE b FROM t4 AS a, t4 AS b; # UNLOCK TABLES; # DROP TABLES t1, t4; # --echo # 3.4) ALTER TABLE COPY with RENAME clause to different schema. # --echo # # DROP TABLES IF EXISTS t1; # CREATE TABLE t1 (i INT); # CREATE DATABASE mysqltest; # LOCK TABLES t1 WRITE; # ALTER TABLE t1 ADD COLUMN k INT; # ALTER TABLE t1 RENAME TO mysqltest.t1, ALGORITHM=COPY; # --echo # Table is available in new schema under LOCK TABLES. # SELECT * FROM mysqltest.t1; # connection con1; # --echo # Access by new name from other connections should be blocked. # SET @@lock_wait_timeout= 1; # --error ER_LOCK_WAIT_TIMEOUT # SELECT * FROM mysqltest.t1; # SET @@lock_wait_timeout= @old_lock_wait_timeout; # --echo # But not to old schema and table name. # --error ER_NO_SUCH_TABLE # SELECT * FROM t1; # --echo # Also IX lock on new schema should be kept. # SET @@lock_wait_timeout= 1; # --error ER_LOCK_WAIT_TIMEOUT # ALTER DATABASE mysqltest CHARACTER SET latin1; # SET @@lock_wait_timeout= @old_lock_wait_timeout; # connection default; # UNLOCK TABLES; # DROP DATABASE mysqltest;