You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6132 lines
183 KiB
6132 lines
183 KiB
#
|
|
# We need the Debug Sync Facility.
|
|
#
|
|
--source include/have_debug_sync.inc
|
|
--source include/force_myisam_default.inc
|
|
--source include/have_myisam.inc
|
|
|
|
# We need InnoDB tables for some of the tests.
|
|
|
|
# Save the initial number of concurrent sessions.
|
|
--source include/count_sessions.inc
|
|
|
|
|
|
# Clean up resources used in this test case.
|
|
--disable_warnings
|
|
SET DEBUG_SYNC= 'RESET';
|
|
--enable_warnings
|
|
|
|
#
|
|
# Test the case of when a exclusive lock request waits for a
|
|
# shared lock being upgraded to a exclusive lock.
|
|
#
|
|
|
|
connect (con1,localhost,root,,test,,);
|
|
connect (con2,localhost,root,,test,,);
|
|
connect (con3,localhost,root,,test,,);
|
|
|
|
connection default;
|
|
|
|
--disable_warnings
|
|
drop table if exists t1,t2,t3;
|
|
--enable_warnings
|
|
|
|
create table t1 (i int);
|
|
create table t2 (i int);
|
|
|
|
--echo connection: default
|
|
lock tables t2 read;
|
|
|
|
connection con1;
|
|
--echo connection: con1
|
|
set debug_sync='mdl_upgrade_lock SIGNAL parked WAIT_FOR go';
|
|
--send alter table t1 rename t3
|
|
|
|
connection default;
|
|
--echo connection: default
|
|
set debug_sync= 'now WAIT_FOR parked';
|
|
|
|
connection con2;
|
|
--echo connection: con2
|
|
set debug_sync='mdl_acquire_lock_wait SIGNAL go';
|
|
--send drop table t1,t2
|
|
|
|
connection con1;
|
|
--echo connection: con1
|
|
--reap
|
|
|
|
connection default;
|
|
--echo connection: default
|
|
unlock tables;
|
|
|
|
connection con2;
|
|
--echo connection: con2
|
|
--error ER_BAD_TABLE_ERROR
|
|
--reap
|
|
|
|
connection default;
|
|
drop table t3;
|
|
|
|
disconnect con1;
|
|
disconnect con2;
|
|
disconnect con3;
|
|
|
|
# Clean up resources used in this test case.
|
|
--disable_warnings
|
|
SET DEBUG_SYNC= 'RESET';
|
|
--enable_warnings
|
|
|
|
|
|
--echo #
|
|
--echo # Basic test coverage for type-of-operation aware metadata locks.
|
|
--echo #
|
|
--disable_warnings
|
|
drop table if exists t1, t2, t3;
|
|
--enable_warnings
|
|
connect(mdl_con1,localhost,root,,);
|
|
connect(mdl_con2,localhost,root,,);
|
|
connect(mdl_con3,localhost,root,,);
|
|
connection default;
|
|
set debug_sync= 'RESET';
|
|
create table t1 (c1 int);
|
|
|
|
--echo #
|
|
--echo # A) First let us check compatibility rules between differend kinds of
|
|
--echo # type-of-operation aware metadata locks.
|
|
--echo # Of course, these rules are already covered by the tests scattered
|
|
--echo # across the test suite. But it still makes sense to have one place
|
|
--echo # which covers all of them.
|
|
--echo #
|
|
|
|
--echo # 1) Acquire S (simple shared) lock on the table (by using HANDLER):
|
|
--echo #
|
|
handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that S, SH, SR, SW and SWLP locks are compatible with it.
|
|
handler t1 open t;
|
|
handler t close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
insert into t1 values (1);
|
|
insert low_priority into t1 values (1);
|
|
--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE
|
|
--echo # which will fail when constructing .frm and thus obtaining SU metadata
|
|
--echo # lock.
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo # Check that SRO lock is compatible with S lock.
|
|
lock table t1 read;
|
|
select count(*) from t1;
|
|
unlock tables;
|
|
--echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE
|
|
--echo # which will fail during copying the table and thus obtaining SNW metadata
|
|
--echo # lock.
|
|
--error ER_DUP_ENTRY
|
|
alter table t1 add primary key (c1);
|
|
--echo # Check that SNRW lock is compatible with S lock.
|
|
lock table t1 write;
|
|
insert into t1 values (1);
|
|
unlock tables;
|
|
--echo # Check that X lock is incompatible with S lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above RENAME is blocked because of S lock.
|
|
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
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Unblock RENAME TABLE.
|
|
handler t1 close;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
rename table t2 to t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that upgrade from SNW to X is blocked by presence of S lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add column c2 int;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above ALTER TABLE is blocked because of S lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column c2 int";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Unblock ALTER TABLE.
|
|
handler t1 close;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
alter table t1 drop column c2;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that upgrade from SNRW to X is blocked by presence of S lock.
|
|
lock table t1 write;
|
|
--echo # Sending:
|
|
--send alter table t1 add column c2 int;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above upgrade of SNRW to X in ALTER TABLE is blocked
|
|
--echo # because of S lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column c2 int";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Unblock ALTER TABLE.
|
|
handler t1 close;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
alter table t1 drop column c2;
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo # 2) Acquire SH (shared high-priority) lock on the table.
|
|
--echo # We have to involve DEBUG_SYNC facility for this as usually
|
|
--echo # such kind of locks are short-lived.
|
|
--echo #
|
|
set debug_sync= 'after_open_table_mdl_shared_to_fetch_stats SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that S, SH, SR, SW and SWLP locks are compatible with it.
|
|
handler t1 open;
|
|
handler t1 close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
insert into t1 values (1), (1);
|
|
delete low_priority from t1 limit 1;
|
|
--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE
|
|
--echo # which will fail when constructing .frm and thus obtaining SU metadata
|
|
--echo # lock.
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo # Check that SRO lock is compatible with SH lock.
|
|
lock table t1 read;
|
|
select count(*) from t1;
|
|
unlock tables;
|
|
--echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE
|
|
--echo # which will fail during copying the table and thus obtaining SNW metadata
|
|
--echo # lock.
|
|
--error ER_DUP_ENTRY
|
|
alter table t1 add primary key (c1);
|
|
--echo # Check that SNRW lock is compatible with SH lock.
|
|
lock table t1 write;
|
|
delete from t1 limit 1;
|
|
unlock tables;
|
|
--echo # Check that X lock is incompatible with SH lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above RENAME is blocked because of SH lock.
|
|
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
|
|
--echo # Unblock RENAME TABLE.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping SELECT ... FROM I_S.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
rename table t2 to t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'after_open_table_mdl_shared_to_fetch_stats SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that upgrade from SNW to X is blocked by presence of SH lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add column c2 int;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above ALTER TABLE is blocked because of SH lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column c2 int";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping SELECT ... FROM I_S.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
alter table t1 drop column c2;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'after_open_table_mdl_shared_to_fetch_stats SIGNAL locked WAIT_FOR finish';
|
|
--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that upgrade from SNRW to X is blocked by presence of S lock.
|
|
lock table t1 write;
|
|
--echo # Sending:
|
|
--send alter table t1 add column c2 int;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above upgrade of SNRW to X in ALTER TABLE is blocked
|
|
--echo # because of S lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column c2 int";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping SELECT ... FROM I_S.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
alter table t1 drop column c2;
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo #
|
|
--echo # 3) Acquire SR lock on the table.
|
|
--echo #
|
|
--echo #
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that S, SH, SR, SW and SWLP locks are compatible with it.
|
|
handler t1 open;
|
|
handler t1 close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
insert into t1 values (1), (1);
|
|
delete low_priority from t1 limit 1;
|
|
--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE
|
|
--echo # which will fail when constructing .frm and thus obtaining SU metadata
|
|
--echo # lock.
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo # Check that SRO lock is compatible with SR lock.
|
|
lock table t1 read;
|
|
select count(*) from t1;
|
|
unlock tables;
|
|
--echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE
|
|
--echo # which will fail during copying the table and thus obtaining SNW metadata
|
|
--echo # lock.
|
|
--error ER_DUP_ENTRY
|
|
alter table t1 add primary key (c1);
|
|
--echo # Check that SNRW lock is not compatible with SR lock.
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above LOCK TABLES is blocked because of SR lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLES.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLES.
|
|
--reap
|
|
delete from t1 limit 1;
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that X lock is incompatible with SR lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above RENAME is blocked because of SR lock.
|
|
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
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
rename table t2 to t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that upgrade from SNW to X is blocked by presence of SR lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add column c2 int;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above ALTER TABLE is blocked because of SR lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column c2 int";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Unblock ALTER TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
alter table t1 drop column c2;
|
|
--echo #
|
|
--echo # There is no need to check that upgrade from SNRW to X is blocked
|
|
--echo # by presence of SR lock because SNRW is incompatible with SR anyway.
|
|
--echo #
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo #
|
|
--echo # 4) Acquire SW lock on the table.
|
|
--echo #
|
|
--echo #
|
|
begin;
|
|
insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that S, SH, SR, SW and SWLP locks are compatible with it.
|
|
handler t1 open;
|
|
handler t1 close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
--echo # Disable result log to make test robust against
|
|
--echo # effects of concurrent insert.
|
|
--disable_result_log
|
|
select * from t1;
|
|
--enable_result_log
|
|
insert into t1 values (1);
|
|
delete low_priority from t1 limit 1;
|
|
--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE
|
|
--echo # which will fail when constructing .frm and thus obtaining SU metadata
|
|
--echo # lock.
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo # Check that SRO lock is not compatible with SW lock;
|
|
--echo # Sending:
|
|
--send lock table t1 read;
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above LOCK TABLE READ is blocked because of SW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 read";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLE READ.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLE READ.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
begin;
|
|
insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SNW lock is not compatible with SW lock.
|
|
--echo # Again we use ALTER TABLE which fails during copying
|
|
--echo # the table to avoid upgrade of SNW -> X.
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above ALTER TABLE is blocked because of SW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
begin;
|
|
insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SNRW lock is not compatible with SW lock.
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above LOCK TABLES is blocked because of SW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLES.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLES.
|
|
--reap
|
|
delete from t1 limit 2;
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
begin;
|
|
insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that X lock is incompatible with SW lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above RENAME is blocked because of SW lock.
|
|
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
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
rename table t2 to t1;
|
|
--echo #
|
|
--echo # There is no need to check that upgrade from SNW/SNRW to X is
|
|
--echo # blocked by presence of SW lock because SNW/SNRW is incompatible
|
|
--echo # with SW anyway.
|
|
--echo #
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo #
|
|
--echo # 5) Acquire SWLP lock on the table.
|
|
--echo #
|
|
--echo #
|
|
begin;
|
|
insert low_priority into t1 values (1), (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that S, SH, SR, SW and SWLP locks are compatible with it.
|
|
handler t1 open;
|
|
handler t1 close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
--echo # Disable result log to make test robust against
|
|
--echo # effects of concurrent insert.
|
|
--disable_result_log
|
|
select * from t1;
|
|
--enable_result_log
|
|
delete from t1 limit 1;
|
|
delete low_priority from t1 limit 1;
|
|
--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE
|
|
--echo # which will fail when constructing .frm and thus obtaining SU metadata
|
|
--echo # lock.
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo # Check that SRO lock is not compatible with SWLP lock;
|
|
--echo # Sending:
|
|
--send lock table t1 read;
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above LOCK TABLE READ is blocked because of SWLP lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 read";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLE READ.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLE READ.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
begin;
|
|
insert low_priority into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SNW lock is not compatible with SWLP lock.
|
|
--echo # Again we use ALTER TABLE which fails during copying
|
|
--echo # the table to avoid upgrade of SNW -> X.
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above ALTER TABLE is blocked because of SWLP lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
begin;
|
|
delete low_priority from t1 limit 2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SNRW lock is not compatible with SWLP lock.
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above LOCK TABLES is blocked because of SWLP lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLES.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLES.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
begin;
|
|
insert low_priority into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that X lock is incompatible with SWLP lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above RENAME is blocked because of SW lock.
|
|
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
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
rename table t2 to t1;
|
|
--echo #
|
|
--echo # There is no need to check that upgrade from SNW/SNRW to X is
|
|
--echo # blocked by presence of SWLP lock because SNW/SNRW is incompatible
|
|
--echo # with SWLP anyway.
|
|
--echo #
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo #
|
|
--echo # 6) Acquire SU lock on the table. We have to use DEBUG_SYNC for
|
|
--echo # this, to prevent SU from being immediately upgraded to X.
|
|
--echo #
|
|
set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that S, SH, SR, SW and SWLP locks are compatible with it.
|
|
handler t1 open;
|
|
handler t1 close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
insert into t1 values (1);
|
|
delete low_priority from t1 limit 2;
|
|
--echo # Check that SU lock is incompatible with SU lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above ALTER is blocked because of SU lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTERs.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping first ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping another ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that SRO lock is compatible with SU lock.
|
|
lock tables t1 read;
|
|
unlock tables;
|
|
--echo # Check that SNRW lock is incompatible with SU lock.
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above LOCK TABLES is blocked because of SU lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER and thus LOCK TABLES.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLES
|
|
--reap
|
|
insert into t1 values (1);
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that X lock is incompatible with SU lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above RENAME is blocked because of SU lock.
|
|
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
|
|
--echo # Unblock ALTER and thus RENAME TABLE.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Now we have ALTER TABLE with SU->SNW and RENAME TABLE with pending
|
|
--echo # X-lock. In this case ALTER TABLE should be chosen as victim.
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_LOCK_DEADLOCK
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME TABLE
|
|
--reap
|
|
--echo # Revert back to original state of things.
|
|
rename table t2 to t1;
|
|
--echo #
|
|
--echo # There is no need to check that upgrade from SNW/SNRW to X is
|
|
--echo # blocked by presence of another SU lock because SNW/SNRW is
|
|
--echo # incompatible with SU anyway.
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo #
|
|
--echo # 7) Acquire SRO lock on the table.
|
|
--echo #
|
|
--echo #
|
|
lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that S, SH and SR locks are compatible with it.
|
|
handler t1 open;
|
|
handler t1 close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
--echo # Check that SW lock is incompatible with SRO lock.
|
|
--echo # Sending:
|
|
--send delete from t1 limit 2;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above DELETE is blocked because of SRO lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete from t1 limit 2";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock DELETE.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SWLP lock is incompatible with SRO lock.
|
|
--echo # Sending:
|
|
--send insert low_priority into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above INSERT is blocked because of SRO lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert low_priority into t1 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock INSERT.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping INSERT.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SU lock is compatible with SRO lock.
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo # Check that SRO lock is compatible with SRO lock.
|
|
lock table t1 read;
|
|
unlock tables;
|
|
--echo # Check that SNW lock is compatible with SRO lock.
|
|
--echo # Again we use ALTER TABLE which fails during copying
|
|
--echo # the table to avoid upgrade of SNW -> X.
|
|
--error ER_DUP_ENTRY
|
|
alter table t1 add primary key (c1);
|
|
--echo # Check that SNRW lock is incompatible with SRO lock.
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above LOCK TABLES is blocked because of SRO lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock waiting LOCK TABLES.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLES
|
|
--reap
|
|
insert into t1 values (1);
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that X lock is incompatible with SRO lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above RENAME is blocked because of SRO lock.
|
|
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
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME TABLE
|
|
--reap
|
|
--echo # Revert back to original state of things.
|
|
rename table t2 to t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that upgrade from SNW to X is blocked by presence of SRO lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add column c2 int;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above ALTER TABLE is blocked because of SRO lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column c2 int";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Unblock ALTER TABLE.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
--echo # Restore the original state of the things.
|
|
alter table t1 drop column c2;
|
|
--echo #
|
|
--echo # There is no need to check that upgrade from SNRW to X is
|
|
--echo # blocked by presence of SRO lock because SNRW is incompatible
|
|
--echo # with SRO anyway.
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo #
|
|
--echo # 8) Acquire SNW lock on the table. We have to use DEBUG_SYNC for
|
|
--echo # this, to prevent SNW from being immediately upgraded to X.
|
|
--echo #
|
|
set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1), lock=shared, algorithm=copy;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that S, SH and SR locks are compatible with it.
|
|
handler t1 open;
|
|
handler t1 close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
--echo # Check that SW lock is incompatible with SNW lock.
|
|
--echo # Sending:
|
|
--send delete from t1 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above DELETE is blocked because of SNW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete from t1 limit 1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER and thus DELETE.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1), lock=shared, algorithm=copy;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that SWLP lock is incompatible with SNW lock.
|
|
--echo # Sending:
|
|
--send delete low_priority from t1 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above DELETE is blocked because of SNW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete low_priority from t1 limit 1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1), lock=shared, algorithm=copy;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that SU lock is incompatible with SNW lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above ALTER is blocked because of SNW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTERs.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping first ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping another ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1), lock=shared, algorithm=copy;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that SRO lock is compatible with SNW lock.
|
|
lock tables t1 read;
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Note that we can't easily check SNW vs SNW locks since
|
|
--echo # SNW is only used by ALTER TABLE after upgrading from SU
|
|
--echo # and SU is also incompatible with SNW.
|
|
--echo #
|
|
--echo # Check that SNRW lock is incompatible with SNW lock.
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above LOCK TABLES is blocked because of SNW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER and thus LOCK TABLES.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLES
|
|
--reap
|
|
insert into t1 values (1);
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1), algorithm=copy, lock=shared;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Check that X lock is incompatible with SNW lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above RENAME is blocked because of SNW lock.
|
|
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
|
|
--echo # Unblock ALTER and thus RENAME TABLE.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME TABLE
|
|
--reap
|
|
--echo # Revert back to original state of things.
|
|
rename table t2 to t1;
|
|
--echo #
|
|
--echo # There is no need to check that upgrade from SNW/SNRW to X is
|
|
--echo # blocked by presence of another SNW lock because SNW/SNRW is
|
|
--echo # incompatible with SNW anyway.
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo #
|
|
--echo # 9) Acquire SNRW lock on the table.
|
|
--echo #
|
|
--echo #
|
|
lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that S and SH locks are compatible with it.
|
|
handler t1 open;
|
|
handler t1 close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
--echo # Check that SR lock is incompatible with SNRW lock.
|
|
--echo # Sending:
|
|
--send select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above SELECT is blocked because of SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "select count(*) from t1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock SELECT.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping SELECT.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SW lock is incompatible with SNRW lock.
|
|
--echo # Sending:
|
|
--send delete from t1 limit 2;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above DELETE is blocked because of SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete from t1 limit 2";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock DELETE.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SWLP lock is incompatible with SNRW lock.
|
|
--echo # Sending:
|
|
--send insert low_priority into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above INSERT is blocked because of SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert low_priority into t1 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock INSERT.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping INSERT.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SU lock is incompatible with SNRW lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above ALTER is blocked because of SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SRO lock is incompatible with SNRW lock.
|
|
--echo # Sending:
|
|
--send lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above LOCK TABLE READ is blocked because of SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 read";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLE READ.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLE READ.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Note that we can't easily check SNW vs SNRW locks since
|
|
--echo # SNW is only used by ALTER TABLE after upgrading from SU
|
|
--echo # and SU is also incompatible with SNRW.
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that SNRW lock is incompatible with SNRW lock.
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above LOCK TABLES is blocked because of SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock waiting LOCK TABLES.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLES
|
|
--reap
|
|
insert into t1 values (1);
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that X lock is incompatible with SNRW lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Check that the above RENAME is blocked because of SNRW lock.
|
|
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
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME TABLE
|
|
--reap
|
|
--echo # Revert back to original state of things.
|
|
rename table t2 to t1;
|
|
--echo #
|
|
--echo # There is no need to check that upgrade from SNW/SNRW to X is
|
|
--echo # blocked by presence of another SNRW lock because SNW/SNRW is
|
|
--echo # incompatible with SNRW anyway.
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo #
|
|
--echo # 10) Now do the same round of tests for X lock. We use additional
|
|
--echo # table to get long-lived lock of this type.
|
|
--echo #
|
|
create table t2 (c1 int);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Take a lock on t2, so RENAME TABLE t1 TO t2 will get blocked
|
|
--echo # after acquiring X lock on t1.
|
|
lock tables t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
|
|
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
|
|
--echo # Check that S lock in incompatible with X lock.
|
|
--echo # Sending:
|
|
--send handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above HANDLER statement is blocked because of X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "handler t1 open";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping HANDLER.
|
|
--reap
|
|
handler t1 close;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Prepare for blocking RENAME TABLE.
|
|
lock tables t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
|
|
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
|
|
--echo # Check that SH lock in incompatible with X lock.
|
|
--echo # Sending:
|
|
--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above SELECT ... FROM I_S ... statement is blocked
|
|
--echo # because of X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info like "select table_name, table_type, auto_increment%";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping SELECT ... FROM I_S.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Prepare for blocking RENAME TABLE.
|
|
lock tables t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
|
|
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
|
|
--echo # Check that SR lock in incompatible with X lock.
|
|
--echo # Sending:
|
|
--send select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above SELECT statement is blocked
|
|
--echo # because of X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "select count(*) from t1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping SELECT.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Prepare for blocking RENAME TABLE.
|
|
lock tables t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
|
|
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
|
|
--echo # Check that SW lock in incompatible with X lock.
|
|
--echo # Sending:
|
|
--send delete from t1 limit 2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above DELETE statement is blocked
|
|
--echo # because of X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete from t1 limit 2";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Prepare for blocking RENAME TABLE.
|
|
lock tables t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
|
|
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
|
|
--echo # Check that SWLP lock in incompatible with X lock.
|
|
--echo # Sending:
|
|
--send insert low_priority into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above INSERT statement is blocked
|
|
--echo # because of X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert low_priority into t1 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping INSERT.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Prepare for blocking RENAME TABLE.
|
|
lock tables t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
|
|
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
|
|
--echo # Check that SU lock is incompatible with X lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above ALTER statement is blocked
|
|
--echo # because of X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Prepare for blocking RENAME TABLE.
|
|
lock tables t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
|
|
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
|
|
--echo # Check that SRO lock is incompatible with X lock.
|
|
--echo # Sending:
|
|
--send lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above LOCK TABLE READ statement is blocked
|
|
--echo # because of X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 read";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLE READ.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Note that we can't easily check SNW vs X locks since
|
|
--echo # SNW is only used by ALTER TABLE after upgrading from SU
|
|
--echo # and SU is also incompatible with X.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Prepare for blocking RENAME TABLE.
|
|
lock tables t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
|
|
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
|
|
--echo # Check that SNRW lock is incompatible with X lock.
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above LOCK TABLE statement is blocked
|
|
--echo # because of X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLE.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Prepare for blocking RENAME TABLE.
|
|
lock tables t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME has acquired X lock on t1 and is waiting for t2.
|
|
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
|
|
--echo # Check that X lock is incompatible with X lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t3;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above RENAME statement is blocked
|
|
--echo # because of X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "rename table t1 to t3";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping RENAME.
|
|
--reap
|
|
rename table t3 to t1;
|
|
|
|
--echo #
|
|
--echo # B) Now let us test compatibility in cases when both locks
|
|
--echo # are pending. I.e. let us test rules for priorities between
|
|
--echo # different types of metadata locks.
|
|
--echo #
|
|
--echo # Note: No tests for pending SU lock as this lock requires
|
|
--echo # even stronger active or pending lock.
|
|
--echo #
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo #
|
|
--echo # 1) Check compatibility for pending SW lock.
|
|
--echo #
|
|
--echo # Acquire SRO lock in order to create pending SW lock later.
|
|
lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending SW lock.
|
|
--echo # Sending:
|
|
--send insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that INSERT is waiting with pending SW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert into t1 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that S, SH, SR locks are compatible with pending SW
|
|
handler t1 open t;
|
|
handler t close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
--echo # Can't check if SW and SWLP are compatible with pending SW
|
|
--echo # as they are not compatible with active SRO.
|
|
--echo #
|
|
--echo # Check that SU lock is compatible with pending SW lock
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo # Check that SRO lock is not compatible with pending SW lock
|
|
--echo # Sending:
|
|
--send lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that LOCK TABLE is waiting due to pending SW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 read";
|
|
--source include/wait_condition.inc
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping INSERT
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping 2nd LOCK TABLE READ
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo #
|
|
--echo # Acquire SRO lock in order to create pending SW lock later.
|
|
lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending SW lock.
|
|
--echo # Sending:
|
|
--send delete from t1 limit 2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that DELETE is waiting with pending SW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete from t1 limit 2";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that SNW lock is compatible with pending SW lock
|
|
--error ER_DUP_ENTRY
|
|
alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # We can't do similar check for SNRW and X locks because
|
|
--echo # they will also be blocked by active SRO lock.
|
|
--echo #
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo #
|
|
--echo # 2) Check compatibility for pending SWLP lock.
|
|
--echo #
|
|
--echo # Acquire SRO lock in order to create pending SWLP lock later.
|
|
lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending SWLP lock.
|
|
--echo # Sending:
|
|
--send insert low_priority into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that INSERT is waiting with pending SWLP lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert low_priority into t1 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that S, SH, SR locks are compatible with pending SWLP
|
|
handler t1 open t;
|
|
handler t close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
--echo # Can't check if SW and SWLP are compatible with pending SWLP
|
|
--echo # as they are not compatible with active SRO.
|
|
--echo #
|
|
--echo # Check that SU lock is compatible with pending SWLP lock
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo # Check that SRO lock is compatible with pending SWLP lock
|
|
lock table t1 read;
|
|
unlock tables;
|
|
--echo # Check that SNW lock is compatible with pending SWLP lock
|
|
--error ER_DUP_ENTRY
|
|
alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # We can't do similar check for SNRW and X locks because
|
|
--echo # they will also be blocked by active SRO lock.
|
|
--echo #
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping INSERT.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo #
|
|
--echo # 3) Check compatibility for pending SRO lock.
|
|
--echo #
|
|
--echo # Acquire SW lock in order to create pending SRO lock later.
|
|
begin;
|
|
insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending SRO lock.
|
|
--echo # Sending:
|
|
--send lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that LOCK TABLE READ is waiting with pending SRO lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 read";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that S, SH, SR, SW locks are compatible with pending SRO
|
|
handler t1 open t;
|
|
handler t close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
delete from t1 limit 1;
|
|
--echo # Check that SWLP is incompatible with pending SRO
|
|
--echo # Sending:
|
|
--send delete low_priority from t1 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that DELETE is waiting with pending SRO lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete low_priority from t1 limit 1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLE READ
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping LOCK TABLE READ
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending SRO lock.
|
|
--echo # Sending:
|
|
--send lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that LOCK TABLE READ is waiting with pending SRO lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 read";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that SU lock is compatible with pending SRO lock
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo #
|
|
--echo # We can't do similar check for SRO, SNW, SNRW and X locks because
|
|
--echo # they will also be blocked by active SW lock.
|
|
--echo #
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Unblock LOCK TABLE READ.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping LOCK TABLE READ.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo #
|
|
--echo # 4) Check compatibility for pending SNW lock.
|
|
--echo #
|
|
--echo # Acquire SW lock in order to create pending SNW lock later.
|
|
begin;
|
|
insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending SNW lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that ALTER TABLE is waiting with pending SNW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that S, SH and SR locks are compatible with pending SNW
|
|
handler t1 open t;
|
|
handler t close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
select count(*) from t1;
|
|
--echo # Check that SW is incompatible with pending SNW
|
|
--echo # Sending:
|
|
--send delete from t1 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above DELETE is blocked because of pending SNW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete from t1 limit 1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping ALTER.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Acquire SW lock in order to create pending SNW lock later.
|
|
begin;
|
|
insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending SNW lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that ALTER TABLE is waiting with pending SNW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that SWLP is incompatible with pending SNW
|
|
--echo # Sending:
|
|
--send delete low_priority from t1 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above DELETE is blocked because of pending SNW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete low_priority from t1 limit 1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping ALTER.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo #
|
|
--echo # We can't do similar check for SU as ALTER first acquire SU
|
|
--echo # before upgrade to SNW.
|
|
--echo # We can't do similar check for SRO, SNW, SNRW and X locks because
|
|
--echo # they will also be blocked by active SW lock.
|
|
--echo #
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo #
|
|
--echo # 5) Check compatibility for pending SNRW lock.
|
|
--echo #
|
|
--echo # Acquire SR lock in order to create pending SNRW lock.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending SNRW lock.
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that S and SH locks are compatible with pending SNRW
|
|
handler t1 open t;
|
|
handler t close;
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
--echo # Check that SR is incompatible with pending SNRW
|
|
--echo # Sending:
|
|
--send select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above SELECT is blocked because of pending SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "select count(*) from t1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping LOCK TABLE.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping SELECT.
|
|
--reap
|
|
--echo # Restore pending SNRW lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that SW is incompatible with pending SNRW
|
|
--echo # Sending:
|
|
--send insert into t1 values (1),(1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above INSERT is blocked because of pending SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert into t1 values (1),(1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping LOCK TABLE.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping INSERT.
|
|
--reap
|
|
--echo # Restore pending SNRW lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that SWLP is incompatible with pending SNRW
|
|
--echo # Sending:
|
|
--send delete low_priority from t1 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above DELETE is blocked because of pending SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete low_priority from t1 limit 1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping LOCK TABLE.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo # Restore pending SNRW lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that SU lock is compatible with pending SNRW lock
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
alter table t1 add index (not_exist);
|
|
--echo # Check that SRO is incompatible with pending SNRW
|
|
--echo # Sending:
|
|
--send lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above LOCK TABLE READ is blocked because
|
|
--echo # of pending SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 read";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock LOCK TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping LOCK TABLE.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLE READ.
|
|
--reap
|
|
unlock tables;
|
|
--echo # Restore pending SNRW lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that LOCK TABLE is waiting with pending SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that SNW is compatible with pending SNRW
|
|
--echo # So ALTER TABLE statements are not starved by LOCK TABLEs.
|
|
--error ER_DUP_ENTRY
|
|
alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Unblock LOCK TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping LOCK TABLE.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # We can't do similar check for SNRW and X locks because
|
|
--echo # they will also be blocked by active SR lock.
|
|
--echo #
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo #
|
|
--echo # 6) Check compatibility for pending X lock.
|
|
--echo #
|
|
--echo # Acquire SR lock in order to create pending X lock.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending X lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME TABLE is waiting with pending X lock.
|
|
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
|
|
--echo # Check that SH locks are compatible with pending X
|
|
select column_name from information_schema.columns where
|
|
table_schema='test' and table_name='t1';
|
|
--echo # Check that S is incompatible with pending X
|
|
--echo # Sending:
|
|
--send handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above HANDLER OPEN is blocked because of pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "handler t1 open";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping HANDLER t1 OPEN.
|
|
--reap
|
|
handler t1 close;
|
|
--echo # Restore pending X lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending X lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME TABLE is waiting with pending X lock.
|
|
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
|
|
--echo # Check that SR is incompatible with pending X
|
|
--echo # Sending:
|
|
--send select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above SELECT is blocked because of pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "select count(*) from t1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping SELECT.
|
|
--reap
|
|
--echo # Restore pending X lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending X lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME TABLE is waiting with pending X lock.
|
|
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
|
|
--echo # Check that SW is incompatible with pending X
|
|
--echo # Sending:
|
|
--send delete from t1 limit 2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above DELETE is blocked because of pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete from t1 limit 2";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping DELETE.
|
|
--reap
|
|
--echo # Restore pending X lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending X lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME TABLE is waiting with pending X lock.
|
|
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
|
|
--echo # Check that SWLP is incompatible with pending X
|
|
--echo # Sending:
|
|
--send insert low_priority into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above INSERT is blocked because of pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert low_priority into t1 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping INSERT.
|
|
--reap
|
|
--echo # Restore pending X lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending X lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME TABLE is waiting with pending X lock.
|
|
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
|
|
--echo # Check that SU is incompatible with pending X
|
|
--echo # Sending:
|
|
--send alter table t1 add index (not_exist);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above ALTER TABLE is blocked
|
|
--echo # because of pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add index (not_exist)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_KEY_COLUMN_DOES_NOT_EXITS
|
|
--reap
|
|
--echo # Restore pending X lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending X lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME TABLE is waiting with pending X lock.
|
|
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
|
|
--echo # Check that SRO is incompatible with pending X
|
|
--echo # Sending:
|
|
--send lock table t1 read;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above LOCK TABLE READ is blocked
|
|
--echo # because of pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 read";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLE READ.
|
|
--reap
|
|
unlock tables;
|
|
--echo # Restore pending X lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending X lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME TABLE is waiting with pending X lock.
|
|
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
|
|
--echo # Check that SNW is incompatible with pending X
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above ALTER TABLE is blocked because of pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo # Restore pending X lock.
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Add pending X lock.
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that RENAME TABLE is waiting with pending X lock.
|
|
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
|
|
--echo # Check that SNRW is incompatible with pending X
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con3'.
|
|
connection mdl_con3;
|
|
--echo # Check that the above LOCK TABLES is blocked because of pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Unblock RENAME TABLE.
|
|
handler t1 close;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reaping LOCK TABLES.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
|
|
--echo #
|
|
--echo #
|
|
--echo # C) Now let us test how type-of-operation locks are handled in
|
|
--echo # transactional context. Obviously we are mostly interested
|
|
--echo # in conflicting types of locks.
|
|
--echo #
|
|
--echo # Note: No tests for active/pending SU lock since
|
|
--echo # ALTER TABLE is in its own transaction.
|
|
--echo # No tests for active/pending SRO lock since
|
|
--echo # it is pretty similar to SNW lock in this
|
|
--echo # respect.
|
|
--echo #
|
|
|
|
--echo #
|
|
--echo # 1) Let us check how various locks used within transactional
|
|
--echo # context interact with active/pending SNW lock.
|
|
--echo #
|
|
--echo # We start with case when we are acquiring lock on the table
|
|
--echo # which was not used in the transaction before.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Create an active SNW lock on t2.
|
|
--echo # We have to use DEBUG_SYNC facility as otherwise SNW lock
|
|
--echo # will be immediately released (or upgraded to X lock).
|
|
insert into t2 values (1), (1);
|
|
set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t2 add primary key (c1), algorithm=copy, lock=shared;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # SR lock should be acquired without any waiting.
|
|
select count(*) from t2;
|
|
commit;
|
|
--echo # Now let us check that we will wait in case of SW lock.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo # Sending:
|
|
--send insert into t2 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above INSERT is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert into t2 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE and thus INSERT.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap INSERT.
|
|
--reap
|
|
commit;
|
|
--echo #
|
|
--echo # Now let us see what happens when we are acquiring lock on the table
|
|
--echo # which is already used in transaction.
|
|
--echo #
|
|
--echo # *) First, case when transaction which has SR lock on the table also
|
|
--echo # locked in SNW mode acquires yet another SR lock and then tries
|
|
--echo # to acquire SW lock.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Create an active SNW lock on t1.
|
|
set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1), algorithm=copy, lock=shared;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # We should still be able to get SR lock without waiting.
|
|
select count(*) from t1;
|
|
--echo # Since the above ALTER TABLE is not upgrading SNW lock to X by waiting
|
|
--echo # for SW lock we won't create deadlock.
|
|
--echo # So the below INSERT should not end-up with ER_LOCK_DEADLOCK error.
|
|
--echo # Sending:
|
|
--send insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above INSERT is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert into t1 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE and thus INSERT.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap INSERT.
|
|
--reap
|
|
commit;
|
|
--echo #
|
|
--echo # **) Now test in which transaction that has SW lock on the table
|
|
--echo # against which there is pending SNW lock acquires SR and SW
|
|
--echo # locks on this table.
|
|
--echo #
|
|
begin;
|
|
insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Create pending SNW lock on t1.
|
|
--echo # Sending:
|
|
--send alter table t1 add primary key (c1);
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until ALTER TABLE starts waiting for SNW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add primary key (c1)";
|
|
--source include/wait_condition.inc
|
|
--echo # We should still be able to get both SW and SR locks without waiting.
|
|
select count(*) from t1;
|
|
delete from t1 limit 1;
|
|
--echo # Unblock ALTER TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap ALTER TABLE.
|
|
--error ER_DUP_ENTRY
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo # 2) Now similar tests for active SNW lock which is being upgraded
|
|
--echo # to X lock.
|
|
--echo #
|
|
--echo # Again we start with case when we are acquiring lock on the
|
|
--echo # table which was not used in the transaction before.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Start transaction which will prevent SNW -> X upgrade from
|
|
--echo # completing immediately.
|
|
begin;
|
|
select count(*) from t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Create SNW lock pending upgrade to X on t2.
|
|
--echo # Sending:
|
|
--send alter table t2 add column c2 int;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until ALTER TABLE starts waiting X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t2 add column c2 int";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that attempt to acquire SR lock on t2 causes waiting.
|
|
--echo # Sending:
|
|
--send select count(*) from t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above SELECT is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "select count(*) from t2";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap ALTER TABLE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap SELECT.
|
|
--reap
|
|
commit;
|
|
--echo # Do similar check for SW lock.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Start transaction which will prevent SNW -> X upgrade from
|
|
--echo # completing immediately.
|
|
begin;
|
|
select count(*) from t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Create SNW lock pending upgrade to X on t2.
|
|
--echo # Sending:
|
|
--send alter table t2 drop column c2;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until ALTER TABLE starts waiting X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t2 drop column c2";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that attempt to acquire SW lock on t2 causes waiting.
|
|
--echo # Sending:
|
|
--send insert into t2 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above INSERT is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert into t2 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap ALTER TABLE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap INSERT.
|
|
--reap
|
|
commit;
|
|
--echo #
|
|
--echo # Test for the case in which we are acquiring lock on the table
|
|
--echo # which is already used in transaction.
|
|
--echo #
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Create SNW lock pending upgrade to X.
|
|
--echo # Sending:
|
|
--send alter table t1 add column c2 int;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until ALTER TABLE starts waiting X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column c2 int";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that transaction is still able to acquire SR lock.
|
|
select count(*) from t1;
|
|
--echo # Waiting trying to acquire SW lock will cause deadlock and
|
|
--echo # therefore should cause an error.
|
|
--error ER_LOCK_DEADLOCK
|
|
delete from t1 limit 1;
|
|
--echo # Unblock ALTER TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap ALTER TABLE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo # 3) Check how various locks used within transactional context
|
|
--echo # interact with active/pending SNRW lock.
|
|
--echo #
|
|
--echo # Once again we start with case when we are acquiring lock on
|
|
--echo # the table which was not used in the transaction before.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
lock table t2 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Attempt to acquire SR should be blocked. It should
|
|
--echo # not cause errors as it does not creates deadlock.
|
|
--echo # Sending:
|
|
--send select count(*) from t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that the above SELECT is blocked
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "select count(*) from t2";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock SELECT.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap SELECT.
|
|
--reap
|
|
commit;
|
|
--echo # Repeat the same test for SW lock.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
lock table t2 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Again attempt to acquire SW should be blocked and should
|
|
--echo # not cause any errors.
|
|
--echo # Sending:
|
|
--send delete from t2 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Check that the above DELETE is blocked
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete from t2 limit 1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock DELETE.
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap DELETE.
|
|
--reap
|
|
commit;
|
|
--echo #
|
|
--echo # Now coverage for the case in which we are acquiring lock on
|
|
--echo # the table which is already used in transaction and against
|
|
--echo # which there is a pending SNRW lock request.
|
|
--echo #
|
|
--echo # *) Let us start with case when transaction has only a SR lock.
|
|
--echo #
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until LOCK TABLE is blocked creating pending request for X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that another instance of SR lock is granted without waiting.
|
|
select count(*) from t1;
|
|
--echo # Attempt to wait for SW lock will lead to deadlock, thus
|
|
--echo # the below statement should end with ER_LOCK_DEADLOCK error.
|
|
--error ER_LOCK_DEADLOCK
|
|
delete from t1 limit 1;
|
|
--echo # Unblock LOCK TABLES.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap LOCK TABLES.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo # **) Now case when transaction has a SW lock.
|
|
--echo #
|
|
begin;
|
|
delete from t1 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Sending:
|
|
--send lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until LOCK TABLE is blocked creating pending request for X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t1 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that both SR and SW locks are granted without waiting
|
|
--echo # and errors.
|
|
select count(*) from t1;
|
|
insert into t1 values (1, 1);
|
|
--echo # Unblock LOCK TABLES.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap LOCK TABLES.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo # 4) Check how various locks used within transactional context
|
|
--echo # interact with active/pending X lock.
|
|
--echo #
|
|
--echo # As usual we start with case when we are acquiring lock on
|
|
--echo # the table which was not used in the transaction before.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Start transaction which will prevent X lock from going away
|
|
--echo # immediately.
|
|
begin;
|
|
select count(*) from t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Create pending X lock on t2.
|
|
--echo # Sending:
|
|
--send rename table t2 to t3;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until RENAME TABLE starts waiting with pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "rename table t2 to t3";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that attempt to acquire SR lock on t2 causes waiting.
|
|
--echo # Sending:
|
|
--send select count(*) from t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above SELECT is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "select count(*) from t2";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap RENAME TABLE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap SELECT.
|
|
--error ER_NO_SUCH_TABLE
|
|
--reap
|
|
commit;
|
|
rename table t3 to t2;
|
|
--echo # The same test for SW lock.
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Start transaction which will prevent X lock from going away
|
|
--echo # immediately.
|
|
begin;
|
|
select count(*) from t2;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Create pending X lock on t2.
|
|
--echo # Sending:
|
|
--send rename table t2 to t3;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until RENAME TABLE starts waiting with pending X lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "rename table t2 to t3";
|
|
--source include/wait_condition.inc
|
|
--echo # Check that attempt to acquire SW lock on t2 causes waiting.
|
|
--echo # Sending:
|
|
--send delete from t2 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con2'.
|
|
connection mdl_con2;
|
|
--echo # Check that the above DELETE is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "delete from t2 limit 1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap RENAME TABLE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap DELETE.
|
|
--error ER_NO_SUCH_TABLE
|
|
--reap
|
|
commit;
|
|
rename table t3 to t2;
|
|
--echo #
|
|
--echo # Coverage for the case in which we are acquiring lock on
|
|
--echo # the table which is already used in transaction and against
|
|
--echo # which there is a pending X lock request.
|
|
--echo #
|
|
--echo # *) The first case is when transaction has only a SR lock.
|
|
--echo #
|
|
begin;
|
|
select count(*) from t1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until RENAME TABLE is blocked creating pending request for X lock.
|
|
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
|
|
--echo # Check that another instance of SR lock is granted without waiting.
|
|
select count(*) from t1;
|
|
--echo # Attempt to wait for SW lock will lead to deadlock, thus
|
|
--echo # the below statement should end with ER_LOCK_DEADLOCK error.
|
|
--error ER_LOCK_DEADLOCK
|
|
delete from t1 limit 1;
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo # **) The second case is when transaction has a SW lock.
|
|
--echo #
|
|
begin;
|
|
delete from t1 limit 1;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Sending:
|
|
--send rename table t1 to t2;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until RENAME TABLE is blocked creating pending request for X lock.
|
|
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
|
|
--echo # Check that both SR and SW locks are granted without waiting
|
|
--echo # and errors.
|
|
select count(*) from t1;
|
|
insert into t1 values (1, 1);
|
|
--echo # Unblock RENAME TABLE.
|
|
commit;
|
|
--echo #
|
|
--echo # Switching to connection 'mdl_con1'.
|
|
connection mdl_con1;
|
|
--echo # Reap RENAME TABLE.
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
|
|
--echo # Clean-up.
|
|
disconnect mdl_con1;
|
|
disconnect mdl_con2;
|
|
disconnect mdl_con3;
|
|
set debug_sync= 'RESET';
|
|
drop table t1, t2;
|
|
|
|
|
|
--echo #
|
|
--echo # Additional coverage for some scenarios in which use of S and SR
|
|
--echo # metadata locks by HANDLER statement might have caused deadlocks.
|
|
--echo #
|
|
--disable_warnings
|
|
drop table if exists t1, t2;
|
|
--enable_warnings
|
|
connect(handler_con1,localhost,root,,);
|
|
connect(handler_con2,localhost,root,,);
|
|
connection default;
|
|
create table t1 (i int);
|
|
create table t2 (j int);
|
|
insert into t1 values (1);
|
|
|
|
--echo #
|
|
--echo # First, check scenario in which we upgrade SNRW lock to X lock
|
|
--echo # on a table while having HANDLER READ trying to acquire SR
|
|
--echo # on the same table.
|
|
--echo #
|
|
handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
lock table t1 write;
|
|
--echo # Upgrade SNRW to X lock.
|
|
--echo # Sending:
|
|
--send alter table t1 add column j int;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con2'.
|
|
connection handler_con2;
|
|
--echo # Wait until ALTER is blocked during upgrade.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column j int";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # The below statement should not cause deadlock.
|
|
--send handler t1 read first;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Reap ALTER TABLE.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap HANDLER READ.
|
|
--reap
|
|
handler t1 close;
|
|
|
|
--echo #
|
|
--echo # Now, check scenario in which upgrade of SNRW lock to X lock
|
|
--echo # can be blocked by HANDLER which is open in connection currently
|
|
--echo # waiting to get SW lock owned by connection doing upgrade.
|
|
--echo #
|
|
handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
lock table t1 write, t2 read;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Execute statement which will be blocked on SRO lock
|
|
--echo # owned by connection 'handler_con1'.
|
|
--echo # Sending:
|
|
--send insert into t2 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Wait until INSERT is blocked due to SRO lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert into t2 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Sending 'alter table t1 drop column j'. It should not cause
|
|
--echo # deadlock.
|
|
send alter table t1 drop column j;
|
|
--echo # Switching to connection 'handler_con2'.
|
|
connection handler_con2;
|
|
--echo # Wait until ALTER is blocked during upgrade.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 drop column j";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap INSERT.
|
|
--error ER_LOCK_DEADLOCK
|
|
--reap
|
|
handler t1 close;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Reaping 'alter table t1 drop column j'
|
|
--reap
|
|
unlock tables;
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
|
|
--echo # Then, check the scenario in which upgrade of SNRW lock to X
|
|
--echo # lock is blocked by HANDLER which is open in connection currently
|
|
--echo # waiting to get SW lock on the same table.
|
|
--echo #
|
|
handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
lock table t1 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # The below insert should be blocked because active SNRW lock on 't1'.
|
|
--echo # Sending:
|
|
--send insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Wait until INSERT is blocked because of SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert into t1 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # The below ALTER TABLE will be blocked because of presence of HANDLER.
|
|
--echo # Sending:
|
|
--send alter table t1 add column j int;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # INSERT should be chosen as victim for resolving deadlock.
|
|
--echo # Reaping INSERT.
|
|
--error ER_LOCK_DEADLOCK
|
|
--reap
|
|
--echo # Close HANDLER to unblock ALTER TABLE.
|
|
handler t1 close;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
|
|
--echo #
|
|
--echo # Then, test in which upgrade of SNRW lock to X lock is blocked
|
|
--echo # by HANDLER which is open in connection currently waiting to get
|
|
--echo # SR lock on the table on which lock is upgraded.
|
|
--echo #
|
|
handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
lock table t1 write, t2 write;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # The below insert should be blocked because active SNRW lock on 't1'.
|
|
--echo # Sending:
|
|
--send insert into t2 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Wait until INSERT is blocked because of SNRW lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert into t2 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # The below ALTER TABLE will be blocked because of presence of HANDLER.
|
|
--echo # Sending:
|
|
--send alter table t1 drop column j;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # INSERT should be chosen as victim for resolving deadlock.
|
|
--echo # Reaping INSERT.
|
|
--error ER_LOCK_DEADLOCK
|
|
--reap
|
|
--echo # Close HANDLER to unblock ALTER TABLE.
|
|
handler t1 close;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
|
|
--echo #
|
|
--echo # Finally, check scenario in which upgrade of SNRW lock to X lock
|
|
--echo # can be blocked by HANDLER which is open in connection currently
|
|
--echo # waiting to get thr_lock.c lock owned by connection doing upgrade.
|
|
--echo #
|
|
handler t1 open;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
lock table t1 write, t2 read local;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Execute statement which will be blocked on thr_lock.c lock
|
|
--echo # owned by connection 'handler_con1'.
|
|
--echo # Sending:
|
|
--send update t2 set j=3;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Wait until UPDATE is blocked due to thr_lock.c lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table level lock" and
|
|
info = "update t2 set j=3";
|
|
--source include/wait_condition.inc
|
|
--echo # Sending 'alter table t1 add column j'. It should not cause
|
|
--echo # deadlock.
|
|
send alter table t1 add column j int;
|
|
--echo # Switching to connection 'handler_con2'.
|
|
connection handler_con2;
|
|
--echo # Wait until ALTER is blocked during upgrade.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column j int";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap UPDATE.
|
|
--error ER_LOCK_ABORTED
|
|
--reap
|
|
handler t1 close;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Reaping 'alter table t1 drop column j'
|
|
--reap
|
|
unlock tables;
|
|
|
|
--echo #
|
|
--echo # Also cover situation when HANDLER READ is aborted while waiting on
|
|
--echo # thr_lock.c lock in order to avoid deadlock due to another connection
|
|
--echo # performing DDL on another table open by HANDLER in the first one.
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
handler t1 open;
|
|
handler t2 open;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 write, t2 read local;
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con2'.
|
|
connection handler_con2;
|
|
--echo # Execute statement which will be blocked on thr_lock.c lock
|
|
--echo # owned by connection 'default' and will block further attempts
|
|
--echo # to read from 't2.
|
|
--echo # Sending:
|
|
--send update t2 set j=3;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until UPDATE is blocked due to thr_lock.c lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table level lock" and
|
|
info = "update t2 set j=3";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Sending
|
|
--send handler t2 read first;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until HANDLER READ is blocked due to pending thr_lock.c lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table level lock" and
|
|
info = "handler t2 read first";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # ALTER TABLE t1 should not block. HANDLER t2 READ should get aborted
|
|
--echo # from its wait on thr_lock.c lock and 'handler_con1' should re-open
|
|
--echo # tables opened by HANDLER statemets.
|
|
alter table t1 drop column j;
|
|
unlock tables;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con2'.
|
|
connection handler_con2;
|
|
--echo # Reap UPDATE
|
|
--reap
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'handler_con1'.
|
|
connection handler_con1;
|
|
--echo # Reap HANDLER READ
|
|
--reap
|
|
handler t1 close;
|
|
handler t2 close;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Clean-up.
|
|
disconnect handler_con1;
|
|
disconnect handler_con2;
|
|
drop tables t1, t2;
|
|
|
|
|
|
--echo #
|
|
--echo # Test coverage for basic deadlock detection in metadata
|
|
--echo # locking subsystem.
|
|
--echo #
|
|
--disable_warnings
|
|
drop tables if exists t0, t1, t2, t3, t4, t5;
|
|
--enable_warnings
|
|
set debug_sync= 'RESET';
|
|
|
|
connect(deadlock_con1,localhost,root,,);
|
|
connect(deadlock_con2,localhost,root,,);
|
|
connect(deadlock_con3,localhost,root,,);
|
|
connection default;
|
|
create table t1 (i int);
|
|
create table t2 (j int);
|
|
create table t3 (k int);
|
|
create table t4 (k int);
|
|
|
|
--echo #
|
|
--echo # Test for the case in which no deadlock occurs.
|
|
--echo #
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
begin;
|
|
insert into t1 values (1);
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
begin;
|
|
insert into t2 values (1);
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Send:
|
|
--send rename table t2 to t0, t3 to t2, t0 to t3;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Wait until the above RENAME TABLE is blocked because it has to wait
|
|
--echo # for 'deadlock_con2' which holds shared metadata lock on 't2'.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "rename table t2 to t0, t3 to t2, t0 to t3";
|
|
--source include/wait_condition.inc
|
|
--echo # The below statement should wait for exclusive metadata lock
|
|
--echo # on 't2' to go away and should not produce ER_LOCK_DEADLOCK
|
|
--echo # as no deadlock is possible in this situation.
|
|
--echo # Send:
|
|
--send select * from t2;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Wait until the above SELECT * FROM t2 is starts waiting
|
|
--echo # for an exclusive metadata lock to go away.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "select * from t2";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # Unblock RENAME TABLE by releasing shared metadata lock on t2.
|
|
commit;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap RENAME TABLE.
|
|
--reap
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Reap SELECT.
|
|
--reap
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo #
|
|
--echo # Let us check that in the process of waiting for conflicting lock
|
|
--echo # on table 't2' to go away transaction in connection 'deadlock_con1'
|
|
--echo # has not released metadata lock on table 't1'.
|
|
--echo # Send:
|
|
--send rename table t1 to t0, t3 to t1, t0 to t3;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Wait until the above RENAME TABLE is blocked because it has to wait
|
|
--echo # for 'deadlock_con1' which should still hold shared metadata lock on
|
|
--echo # table 't1'.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "rename table t1 to t0, t3 to t1, t0 to t3";
|
|
--source include/wait_condition.inc
|
|
--echo # Commit transaction to unblock RENAME TABLE.
|
|
commit;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap RENAME TABLE.
|
|
--reap
|
|
|
|
--echo #
|
|
--echo # Test for case when deadlock occurs and should be detected immediately.
|
|
--echo #
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
begin;
|
|
insert into t2 values (2);
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Send:
|
|
--send rename table t2 to t0, t1 to t2, t0 to t1;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Wait until the above RENAME TABLE is blocked because it has to wait
|
|
--echo # for 'deadlock_con1' which holds shared metadata lock on 't2'.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "rename table t2 to t0, t1 to t2, t0 to t1";
|
|
--source include/wait_condition.inc
|
|
--echo #
|
|
--echo # The below statement should not wait as doing so will cause deadlock.
|
|
--echo # Instead it should fail and emit ER_LOCK_DEADLOCK statement and
|
|
--echo # transaction should be rolled back.
|
|
--error ER_LOCK_DEADLOCK
|
|
select * from t1;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap RENAME TABLE.
|
|
--reap
|
|
|
|
--echo #
|
|
--echo # Test for the case in which deadlock also occurs but not immediately.
|
|
--echo #
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
begin;
|
|
insert into t2 values (1);
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
lock table t1 write;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # The below SELECT statement should wait for metadata lock
|
|
--echo # on table 't1' and should not produce ER_LOCK_DEADLOCK
|
|
--echo # immediately as no deadlock is possible at the moment.
|
|
--send select * from t1;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Wait until the above SELECT * FROM t1 is starts waiting
|
|
--echo # for an UNRW metadata lock to go away.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and info = "select * from t1";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # Send RENAME TABLE statement that will deadlock with the
|
|
--echo # SELECT statement and thus should abort the latter.
|
|
--send rename table t1 to t0, t2 to t1, t0 to t2;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait till above RENAME TABLE is blocked while holding
|
|
--echo # pending X lock on t1.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "rename table t1 to t0, t2 to t1, t0 to t2";
|
|
--source include/wait_condition.inc
|
|
--echo # Allow the above RENAME TABLE to acquire lock on t1 and
|
|
--echo # create pending lock on t2 thus creating deadlock.
|
|
unlock tables;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Since the latest RENAME TABLE entered in deadlock with SELECT
|
|
--echo # statement the latter should be aborted and emit ER_LOCK_DEADLOCK
|
|
--echo # error and transaction should be rolled back.
|
|
--echo # Reap SELECT * FROM t1.
|
|
--error ER_LOCK_DEADLOCK
|
|
--reap
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Reap RENAME TABLE ... .
|
|
--reap;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
|
|
drop tables t1, t2, t3, t4;
|
|
|
|
--echo #
|
|
--echo # Now, test case which shows that deadlock detection empiric
|
|
--echo # also takes into account requests for metadata lock upgrade.
|
|
--echo #
|
|
create table t1 (i int);
|
|
insert into t1 values (1);
|
|
--echo # Avoid race which occurs when SELECT in 'deadlock_con1' connection
|
|
--echo # accesses table before the above INSERT unlocks the table and thus
|
|
--echo # its result becomes visible to other connections.
|
|
select * from t1;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
begin;
|
|
select * from t1;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Send:
|
|
--send alter table t1 add column j int, rename to t2;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Wait until the above ALTER TABLE ... RENAME acquires exclusive
|
|
--echo # metadata lock on 't2' and starts waiting for connection
|
|
--echo # 'deadlock_con1' which holds shared lock on 't1'.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 add column j int, rename to t2";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # The below statement should not wait as it will cause deadlock.
|
|
--echo # An appropriate error should be reported instead and transaction
|
|
--echo # should be rolled back.
|
|
--error ER_LOCK_DEADLOCK
|
|
select * from t2;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap ALTER TABLE ... RENAME.
|
|
--reap
|
|
|
|
drop table t2;
|
|
|
|
--echo #
|
|
--echo # Test that in situation when MDL subsystem detects a deadlock
|
|
--echo # but it turns out that it can be resolved by backing-off locks
|
|
--echo # acquired by one of participating transactions (which is
|
|
--echo # possible when one of transactions consists only of currently
|
|
--echo # executed statement, e.g. in autocommit mode) no error is
|
|
--echo # reported.
|
|
--echo #
|
|
create table t1 (i int);
|
|
create table t2 (j int);
|
|
--echo # Ensure that the below SELECT stops once it has acquired metadata
|
|
--echo # lock on table 't2'.
|
|
set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
|
|
--echo # Sending:
|
|
--send select * from t2, t1
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Wait till SELECT acquires MDL on 't2' and starts waiting for signal.
|
|
set debug_sync= 'now WAIT_FOR locked';
|
|
--echo # Sending:
|
|
--send lock tables t1 write, t2 write
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Wait until LOCK TABLES acquires SNRW lock on 't1' and is blocked
|
|
--echo # while trying to acquire SNRW lock on 't1'.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock tables t1 write, t2 write";
|
|
--source include/wait_condition.inc
|
|
--echo # Resume SELECT execution, this should eventually unblock LOCK TABLES.
|
|
set debug_sync= 'now SIGNAL finish';
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Reaping LOCK TABLES.
|
|
--reap
|
|
unlock tables;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping SELECT. It succeed and not report ER_LOCK_DEADLOCK error.
|
|
--reap
|
|
|
|
drop tables t1, t2;
|
|
|
|
--echo #
|
|
--echo # Test coverage for situation in which a race has happened
|
|
--echo # during deadlock detection process which led to unwarranted
|
|
--echo # ER_LOCK_DEADLOCK error.
|
|
--echo #
|
|
create table t1 (i int);
|
|
|
|
--echo # Ensure that ALTER waits once it has acquired SNW lock.
|
|
set debug_sync='alter_table_copy_after_lock_upgrade SIGNAL parked1 WAIT_FOR go1';
|
|
--echo # Sending:
|
|
--send alter table t1 add column j int
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Wait till ALTER acquires SNW lock and stops.
|
|
set debug_sync='now WAIT_FOR parked1';
|
|
--echo # Ensure that INSERT is paused once it detects that there is
|
|
--echo # a conflicting metadata lock so it has to wait, but before
|
|
--echo # deadlock detection is run.
|
|
set debug_sync='mdl_acquire_lock_wait SIGNAL parked2 WAIT_FOR go2';
|
|
--echo # Sending:
|
|
--send insert into t1 values ()
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Wait till INSERT is paused.
|
|
set debug_sync='now WAIT_FOR parked2';
|
|
--echo # Resume ALTER execution. Eventually it will release its
|
|
--echo # metadata lock and INSERT's request for SW lock will be
|
|
--echo # satisified.
|
|
set debug_sync='now SIGNAL go1';
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
--echo # Add a new request for SNW lock to waiting graph.
|
|
--echo # Sending:
|
|
--send alter table t1 drop column j
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Wait until ALTER is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "alter table t1 drop column j";
|
|
--source include/wait_condition.inc
|
|
--echo # Resume INSERT so it can start deadlock detection.
|
|
--echo #
|
|
--echo # At this point there is a discrepancy between the fact that INSERT's
|
|
--echo # SW lock is already satisfied, but INSERT's connection is still
|
|
--echo # marked as waiting for it. Looking for a loop in waiters graph
|
|
--echo # without additional checks has detected a deadlock (INSERT waits
|
|
--echo # for SW lock; which is not granted because of pending SNW lock from
|
|
--echo # ALTER; which waits for active SW lock from INSERT). Since requests
|
|
--echo # for SW and SNW locks have same weight ALTER was selected as a victim
|
|
--echo # and ended with ER_LOCK_DEADLOCK error.
|
|
set debug_sync='now SIGNAL go2';
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Reaping INSERT.
|
|
--reap
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping ALTER. It should succeed and not produce ER_LOCK_DEADLOCK.
|
|
--reap
|
|
|
|
drop table t1;
|
|
|
|
--echo #
|
|
--echo # Now, test for a situation in which deadlock involves waiting not
|
|
--echo # only in MDL subsystem but also for TDC. Such deadlocks should be
|
|
--echo # successfully detected. If possible, they should be resolved without
|
|
--echo # resorting to ER_LOCK_DEADLOCK error.
|
|
--echo #
|
|
create table t1(i int);
|
|
create table t2(j int);
|
|
--echo # Warm-up data-dictionary and table definition caches
|
|
--disable_query_log
|
|
--disable_result_log
|
|
select * from t1, t2;
|
|
--enable_result_log
|
|
--enable_query_log
|
|
|
|
--echo #
|
|
--echo # First, let us check how we handle a simple scenario involving
|
|
--echo # waits in MDL and TDC.
|
|
--echo #
|
|
set debug_sync= 'RESET';
|
|
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Start a statement, which will acquire SR metadata lock on t1, open it
|
|
--echo # and then stop, before trying to acquire SW lock on t2 and opening it.
|
|
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
|
|
--echo # Sending:
|
|
--send select * from t1 where i in (select j from t2 for update)
|
|
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Wait till the above SELECT stops.
|
|
set debug_sync='now WAIT_FOR parked';
|
|
--echo # The below FLUSH TABLES WITH READ LOCK should acquire
|
|
--echo # SNW locks on t1 and t2 and wait till SELECT closes t1.
|
|
--echo # Sending:
|
|
send flush tables t1, t2 with read lock;
|
|
|
|
--echo # Switching to connection 'deadlock_con3'.
|
|
connection deadlock_con3;
|
|
--echo # Wait until FLUSH TABLES WITH t1, t2 READ LOCK starts waiting
|
|
--echo # for SELECT to close t1.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table flush" and
|
|
info = "flush tables t1, t2 with read lock";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # Resume SELECT, so it tries to acquire SW lock on t1 and blocks,
|
|
--echo # creating a deadlock. This deadlock should be detected and resolved
|
|
--echo # by backing-off SELECT. As a result FTWRL should be able to finish.
|
|
set debug_sync='now SIGNAL go';
|
|
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Reap FLUSH TABLES WITH READ LOCK.
|
|
reap;
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Reap SELECT.
|
|
reap;
|
|
|
|
--echo #
|
|
--echo # The same scenario with a slightly different order of events
|
|
--echo # which emphasizes that setting correct deadlock detector weights
|
|
--echo # for flush waits is important.
|
|
--echo #
|
|
set debug_sync= 'RESET';
|
|
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
set debug_sync='flush_tables_with_read_lock_after_acquire_locks SIGNAL parked WAIT_FOR go';
|
|
|
|
--echo # The below FLUSH TABLES WITH READ LOCK should acquire
|
|
--echo # SNW locks on t1 and t2 and wait on debug sync point.
|
|
--echo # Sending:
|
|
send flush tables t1, t2 with read lock;
|
|
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Wait till FLUSH TABLE WITH READ LOCK stops.
|
|
set debug_sync='now WAIT_FOR parked';
|
|
|
|
--echo # Start statement which will acquire SR metadata lock on t1, open
|
|
--echo # it and then will block while trying to acquire SW lock on t2.
|
|
--echo # Sending:
|
|
send select * from t1 where i in (select j from t2 for update);
|
|
|
|
--echo # Switching to connection 'deadlock_con3'.
|
|
connection deadlock_con3;
|
|
--echo # Wait till the above SELECT blocks.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "select * from t1 where i in (select j from t2 for update)";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # Resume FLUSH TABLES, so it tries to flush t1, thus creating
|
|
--echo # a deadlock. This deadlock should be detected and resolved by
|
|
--echo # backing-off SELECT. As a result FTWRL should be able to finish.
|
|
set debug_sync='now SIGNAL go';
|
|
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Reap FLUSH TABLES WITH READ LOCK.
|
|
reap;
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Reap SELECT.
|
|
reap;
|
|
|
|
--echo #
|
|
--echo # Now a more complex scenario involving two connections
|
|
--echo # waiting for MDL and one for TDC.
|
|
--echo #
|
|
set debug_sync= 'RESET';
|
|
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Start a statement which will acquire SR metadata lock on t2, open it
|
|
--echo # and then stop, before trying to acquire SR on t1 and opening it.
|
|
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
|
|
--echo # Sending:
|
|
send select * from t2, t1;
|
|
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Wait till the above SELECT stops.
|
|
set debug_sync='now WAIT_FOR parked';
|
|
--echo # The below FLUSH TABLES WITH READ LOCK should acquire
|
|
--echo # SNW locks on t2 and wait till SELECT closes t2.
|
|
--echo # Sending:
|
|
send flush tables t2 with read lock;
|
|
|
|
--echo # Switching to connection 'deadlock_con3'.
|
|
connection deadlock_con3;
|
|
--echo # Wait until FLUSH TABLES WITH READ LOCK starts waiting
|
|
--echo # for SELECT to close t2.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table flush" and
|
|
info = "flush tables t2 with read lock";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # The below DROP TABLES should acquire X lock on t1 and start
|
|
--echo # waiting for X lock on t2.
|
|
--echo # Sending:
|
|
send drop tables t1, t2;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until DROP TABLES starts waiting for X lock on t2.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "drop tables t1, t2";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # Resume SELECT, so it tries to acquire SR lock on t1 and blocks,
|
|
--echo # creating a deadlock. This deadlock should be detected and resolved
|
|
--echo # by backing-off SELECT. As a result, FTWRL should be able to finish.
|
|
set debug_sync='now SIGNAL go';
|
|
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Reap FLUSH TABLES WITH READ LOCK.
|
|
reap;
|
|
--echo # Unblock DROP TABLES.
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'deadlock_con3'.
|
|
connection deadlock_con3;
|
|
--echo # Reap DROP TABLES.
|
|
reap;
|
|
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Reap SELECT. It should emit error about missing table.
|
|
--error ER_NO_SUCH_TABLE
|
|
reap;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync= 'RESET';
|
|
|
|
|
|
--echo #
|
|
--echo # Test coverage for scenario when deadlock is caused by LOCK TABLES
|
|
--echo # implicitly acquiring "strong" metadata lock in order that is
|
|
--echo # different from one used by other DDL.
|
|
--echo #
|
|
--echo # Other DDL should not be chosen as a deadlock victim in this case.
|
|
--echo # Instead LOCK TABLES should be chosen as a victim and deadlock
|
|
--echo # should be handled by executing back-off and retry of lock
|
|
--echo # acquisition, without reporting any error to user.
|
|
create table t1(i int);
|
|
create table t2(j int);
|
|
create table t3(j int);
|
|
create trigger t3_bi before insert on t3 for each row insert into t1 values (1);
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
begin;
|
|
select * from t2;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Send:
|
|
--send rename table t1 to t0, t2 to t1, t3 to t2, t0 to t3
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con3'.
|
|
connection deadlock_con3;
|
|
--echo # Wait until the above RENAME TABLE is blocked because it has to wait
|
|
--echo # for 'deadlock_con1' which holds SR lock on 't2'. At this point it
|
|
--echo # should already acquire X lock on 't0' and 't1'.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "rename table t1 to t0, t2 to t1, t3 to t2, t0 to t3";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # The below statement should acquire SNRW lock on 't3' and got
|
|
--echo # blocked trying to acquire SNRW lock on 't1'.
|
|
--echo # Sending:
|
|
--send lock table t3 write;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con1'.
|
|
connection deadlock_con1;
|
|
--echo # Wait until the above LOCK TABLE WRITE starts waiting.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock table t3 write";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo #
|
|
--echo # Unblock RENAME TABLE by releasing SR on t2.
|
|
commit;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con2'.
|
|
connection deadlock_con2;
|
|
--echo # Reap RENAME TABLE. It should succeed.
|
|
--reap
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'deadlock_con3'.
|
|
connection deadlock_con3;
|
|
--echo # Reap LOCK TABLES WRITE. It should succeed too.
|
|
--echo # New version of 't3' should be visible.
|
|
--reap
|
|
select * from t3;
|
|
unlock table;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Clean-up.
|
|
rename table t3 to t0, t2 to t3, t1 to t2, t0 to t1;
|
|
drop trigger t3_bi;
|
|
drop tables t1, t2, t3;
|
|
|
|
disconnect deadlock_con1;
|
|
disconnect deadlock_con2;
|
|
disconnect deadlock_con3;
|
|
|
|
|
|
--echo #
|
|
--echo # Test for a scenario in which FLUSH TABLES <list> WITH READ LOCK
|
|
--echo # used to erroneously release metadata locks.
|
|
--echo #
|
|
connect(con1,localhost,root,,);
|
|
connect(con2,localhost,root,,);
|
|
connection default;
|
|
--disable_warnings
|
|
drop tables if exists t1, t2;
|
|
--enable_warnings
|
|
set debug_sync= 'RESET';
|
|
create table t1(i int);
|
|
create table t2(j int);
|
|
--echo # Warm-up data-dictionary and table definition caches
|
|
--disable_query_log
|
|
--disable_result_log
|
|
select * from t1, t2;
|
|
--enable_result_log
|
|
--enable_query_log
|
|
|
|
--echo # Switching to connection 'con2'.
|
|
connection con2;
|
|
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
|
|
|
|
--echo # The below FLUSH TABLES <list> WITH READ LOCK should acquire
|
|
--echo # SNW locks on t1 and t2, open table t1 and block on the debug
|
|
--echo # sync point.
|
|
--echo # Sending:
|
|
send flush tables t1, t2 with read lock;
|
|
|
|
--echo # Switching to connection 'con1'.
|
|
connection con1;
|
|
--echo # Wait till FLUSH TABLES <list> WITH READ LOCK stops.
|
|
set debug_sync='now WAIT_FOR parked';
|
|
|
|
--echo # Start a statement which will flush all tables and thus
|
|
--echo # invalidate table t1 open by FLUSH TABLES <list> WITH READ LOCK.
|
|
--echo # Sending:
|
|
send flush tables;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait till the above FLUSH TABLES blocks.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table flush" and
|
|
info = "flush tables";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # Resume FLUSH TABLES <list> WITH READ LOCK, so it tries to open t2
|
|
--echo # discovers that its t1 is obsolete and tries to reopen all tables.
|
|
--echo # Such reopen should not cause releasing of SNW metadata locks
|
|
--echo # which would result in assertion failures.
|
|
set debug_sync='now SIGNAL go';
|
|
|
|
--echo # Switching to connection 'con2'.
|
|
connection con2;
|
|
--echo # Reap FLUSH TABLES <list> WITH READ LOCK.
|
|
reap;
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'con1'.
|
|
connection con1;
|
|
--echo # Reap FLUSH TABLES.
|
|
reap;
|
|
|
|
--echo # Clean-up.
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
drop tables t1, t2;
|
|
set debug_sync= 'RESET';
|
|
disconnect con1;
|
|
disconnect con2;
|
|
|
|
|
|
--echo #
|
|
--echo # Test for bug #46748 "Assertion in MDL_context::wait_for_locks()
|
|
--echo # on INSERT + CREATE TRIGGER".
|
|
--echo #
|
|
--disable_warnings
|
|
drop tables if exists t1, t2, t3, t4, t5;
|
|
--enable_warnings
|
|
--echo # Let us simulate scenario in which we open some tables from extended
|
|
--echo # part of prelocking set but then encounter conflicting metadata lock,
|
|
--echo # so have to back-off and wait for it to go away.
|
|
connect (con1root,localhost,root,,test,,);
|
|
connect (con2root,localhost,root,,test,,);
|
|
connection default;
|
|
create table t1 (i int);
|
|
create table t2 (j int);
|
|
create table t3 (k int);
|
|
create table t4 (l int);
|
|
create trigger t1_bi before insert on t1 for each row
|
|
insert into t2 values (new.i);
|
|
create trigger t2_bi before insert on t2 for each row
|
|
insert into t3 values (new.j);
|
|
--echo #
|
|
--echo # Switching to connection 'con1root'.
|
|
connection con1root;
|
|
lock tables t4 read;
|
|
--echo #
|
|
--echo # Switching to connection 'con2root'.
|
|
connection con2root;
|
|
--echo # Send :
|
|
--send rename table t3 to t5, t4 to t3;
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until the above RENAME TABLE adds pending requests for exclusive
|
|
--echo # metadata lock on its tables and blocks due to 't4' being used by LOCK
|
|
--echo # TABLES.
|
|
let $wait_condition= select count(*)= 1 from information_schema.processlist
|
|
where state= 'Waiting for table metadata lock' and
|
|
info='rename table t3 to t5, t4 to t3';
|
|
--source include/wait_condition.inc
|
|
--echo # Send :
|
|
--send insert into t1 values (1);
|
|
--echo #
|
|
--echo # Switching to connection 'con1root'.
|
|
connection con1root;
|
|
--echo # Wait until INSERT statement waits due to encountering pending
|
|
--echo # exclusive metadata lock on 't3'.
|
|
let $wait_condition= select count(*)= 1 from information_schema.processlist
|
|
where state= 'Waiting for table metadata lock' and
|
|
info='insert into t1 values (1)';
|
|
--source include/wait_condition.inc
|
|
unlock tables;
|
|
--echo #
|
|
--echo # Switching to connection 'con2root'.
|
|
connection con2root;
|
|
--echo # Reap RENAME TABLE.
|
|
--reap
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap INSERT.
|
|
--reap
|
|
--echo # Clean-up.
|
|
disconnect con1root;
|
|
disconnect con2root;
|
|
drop tables t1, t2, t3, t5;
|
|
|
|
|
|
--echo #
|
|
--echo # Bug#42546 - Backup: RESTORE fails, thinking it finds an existing table
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1;
|
|
--enable_warnings
|
|
set @save_log_output=@@global.log_output;
|
|
set global log_output=file;
|
|
|
|
connect(con2, localhost, root,,);
|
|
|
|
--echo #
|
|
--echo # Test 1: CREATE TABLE
|
|
--echo #
|
|
|
|
--echo # Connection 2
|
|
connection con2;
|
|
--echo # Start insert on the not-yet existing table
|
|
--echo # Wait after taking the MDL lock
|
|
SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
|
|
--send INSERT INTO t1 VALUES(1,"def")
|
|
|
|
--echo # Connection 1
|
|
connection default;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR locked';
|
|
--echo # Now INSERT has a MDL on the non-existent table t1.
|
|
|
|
--echo #
|
|
--echo # Continue the INSERT once CREATE waits for exclusive lock
|
|
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL finish';
|
|
--echo # Try to create that table.
|
|
--send CREATE TABLE t1 (c1 INT, c2 VARCHAR(100), KEY(c1))
|
|
|
|
--echo # Connection 2
|
|
--echo # Insert fails
|
|
connection con2;
|
|
--error ER_NO_SUCH_TABLE
|
|
--reap
|
|
|
|
--echo # Connection 1
|
|
connection default;
|
|
--reap;
|
|
SET DEBUG_SYNC= 'RESET';
|
|
SHOW TABLES;
|
|
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1;
|
|
--enable_warnings
|
|
|
|
--echo #
|
|
--echo # Test 2: CREATE TABLE LIKE
|
|
--echo #
|
|
|
|
CREATE TABLE t2 (c1 INT, c2 VARCHAR(100), KEY(c1));
|
|
|
|
--echo # Connection 2
|
|
connection con2;
|
|
--echo # Start insert on the not-yet existing table
|
|
--echo # Wait after taking the MDL
|
|
SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish';
|
|
--send INSERT INTO t1 VALUES(1,"def")
|
|
|
|
--echo # Connection 1
|
|
connection default;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR locked';
|
|
--echo # Now INSERT has a MDL on the non-existent table t1.
|
|
|
|
--echo #
|
|
--echo # Continue the INSERT once CREATE waits for exclusive lock
|
|
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL finish';
|
|
--echo # Try to create that table.
|
|
--send CREATE TABLE t1 LIKE t2
|
|
|
|
--echo # Connection 2
|
|
--echo # Insert fails
|
|
connection con2;
|
|
--error ER_NO_SUCH_TABLE
|
|
--reap
|
|
|
|
--echo # Connection 1
|
|
connection default;
|
|
--reap
|
|
SET DEBUG_SYNC= 'RESET';
|
|
SHOW TABLES;
|
|
|
|
DROP TABLE t2;
|
|
disconnect con2;
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1;
|
|
--enable_warnings
|
|
|
|
set global log_output=@save_log_output;
|
|
|
|
|
|
--echo #
|
|
--echo # Bug #46044 "MDL deadlock on LOCK TABLE + CREATE TABLE HIGH_PRIORITY
|
|
--echo # FOR UPDATE"
|
|
--echo #
|
|
--disable_warnings
|
|
drop tables if exists t1, t2;
|
|
--enable_warnings
|
|
connect (con46044, localhost, root,,);
|
|
connect (con46044_2, localhost, root,,);
|
|
connection default;
|
|
create table t1 (i int);
|
|
insert into t1 values(1);
|
|
|
|
--echo # Let us check that we won't deadlock if during filling
|
|
--echo # of I_S table we encounter conflicting metadata lock
|
|
--echo # which owner is in its turn waiting for our connection.
|
|
lock tables t1 read;
|
|
|
|
--echo # Switching to connection 'con46044_2'.
|
|
connection con46044_2;
|
|
--echo # Sending:
|
|
--send lock tables t1 write;
|
|
|
|
--echo # Switching to connection 'con46044'.
|
|
connection con46044;
|
|
|
|
--echo # Waiting until LOCK TABLES WRITE is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "lock tables t1 write";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # Sending:
|
|
--send create table t2 select * from t1;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "create table t2 select * from t1";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # First let us check that SHOW FIELDS/DESCRIBE doesn't
|
|
--echo # gets blocked and emits and error.
|
|
--error ER_WARN_I_S_SKIPPED_TABLE
|
|
show fields from t2;
|
|
|
|
--echo # Now test for I_S query which does not acquire any MDL lock.
|
|
--echo #
|
|
--echo # Query below should not be blocked.
|
|
select column_name from information_schema.columns
|
|
where table_schema='test' and table_name='t2';
|
|
|
|
--echo # Finally, test for I_S query which does full-blown table open.
|
|
--echo #
|
|
--echo # Query below should not be blocked. Warning message should be
|
|
--echo # stored in the 'table_comment' column.
|
|
select table_name, table_type, auto_increment, table_comment
|
|
from information_schema.tables where table_schema='test' and table_name='t2';
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'con46044_2'.
|
|
connection con46044_2;
|
|
--echo # Reaping LOCK TABLES WRITE
|
|
--reap
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'con46044'.
|
|
connection con46044;
|
|
--echo # Reaping CREATE TABLE ... SELECT ... .
|
|
--reap
|
|
drop table t2;
|
|
|
|
--echo #
|
|
--echo # Let us also check queries to I_S wait for conflicting metadata
|
|
--echo # locks to go away instead of skipping table with a warning in cases
|
|
--echo # when deadlock is not possible. This is a nice thing from compatibility
|
|
--echo # and ease of use points of view.
|
|
--echo #
|
|
--echo # We check same three queries to I_S in this new situation.
|
|
|
|
--echo # Switching to connection 'con46044_2'.
|
|
connection con46044_2;
|
|
lock tables t1 write;
|
|
|
|
--echo # Switching to connection 'con46044'.
|
|
connection con46044;
|
|
|
|
--echo # Sending:
|
|
--send create table t2 select * from t1;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "create table t2 select * from t1";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # Let us check that SHOW FIELDS/DESCRIBE gets blocked.
|
|
--echo # Sending:
|
|
--send show fields from t2;
|
|
|
|
--echo # Switching to connection 'con46044_2'.
|
|
connection con46044_2;
|
|
--echo # Wait until SHOW FIELDS gets blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "show fields from t2";
|
|
--source include/wait_condition.inc
|
|
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'con46044'.
|
|
connection con46044;
|
|
--echo # Reaping CREATE TABLE ... SELECT ... .
|
|
--reap
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping SHOW FIELDS ...
|
|
--reap
|
|
drop table t2;
|
|
|
|
--echo # Switching to connection 'con46044_2'.
|
|
connection con46044_2;
|
|
lock tables t1 write;
|
|
|
|
--echo # Switching to connection 'con46044'.
|
|
connection con46044;
|
|
|
|
--echo # Sending:
|
|
--send create table t2 select * from t1;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Waiting until CREATE TABLE ... SELECT ... is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "create table t2 select * from t1";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # Check the I_S query which does not acquire any MDL locks is not blocked.
|
|
--echo # Sending:
|
|
select column_name from information_schema.columns where table_schema='test' and table_name='t2';
|
|
|
|
--echo # Switching to connection 'con46044_2'.
|
|
connection con46044_2;
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'con46044'.
|
|
connection con46044;
|
|
--echo # Reaping CREATE TABLE ... SELECT ... .
|
|
--reap
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
drop table t2;
|
|
|
|
--echo # Switching to connection 'con46044_2'.
|
|
connection con46044_2;
|
|
create table t3 like t1;
|
|
lock tables t3 write;
|
|
|
|
--echo # Switching to connection 'con46044'.
|
|
connection con46044;
|
|
|
|
--echo # Sending:
|
|
--send rename table t1 to t2, t3 to t1, t2 to t3;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Waiting until RENAME TABLE is blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info like "rename table t1 to t2%";
|
|
--source include/wait_condition.inc
|
|
|
|
--echo # Finally, check that I_S query which does full-blown table open
|
|
--echo # also gets blocked.
|
|
--echo # Sending:
|
|
--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
|
|
|
|
--echo # Switching to connection 'con46044_2'.
|
|
connection con46044_2;
|
|
--echo # Wait until SELECT ... FROM I_S.TABLES gets blocked.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info like "select table_name, table_type, auto_increment, table_comment from information_schema.tables%";
|
|
--source include/wait_condition.inc
|
|
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'con46044'.
|
|
connection con46044;
|
|
--echo # Reaping RENAME TABLE
|
|
--reap
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping SELECT ... FROM I_S.TABLES
|
|
--reap
|
|
drop table t3;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Clean-up.
|
|
disconnect con46044;
|
|
disconnect con46044_2;
|
|
drop table t1;
|
|
|
|
|
|
--echo #
|
|
--echo # Test for bug #46273 "MySQL 5.4.4 new MDL: Bug#989 is not fully fixed
|
|
--echo # in case of ALTER".
|
|
--echo #
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
set debug_sync= 'RESET';
|
|
connect (con46273,localhost,root,,test,,);
|
|
connection default;
|
|
create table t1 (c1 int primary key, c2 int, c3 int);
|
|
insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0);
|
|
|
|
begin;
|
|
select * from t1 where c2 = 3;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'con46273'.
|
|
connection con46273;
|
|
set debug_sync='alter_table_copy_after_lock_upgrade SIGNAL alter_table_locked WAIT_FOR alter_go';
|
|
--send alter table t1 add column e int, rename to t2;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
set debug_sync='now WAIT_FOR alter_table_locked';
|
|
set debug_sync='mdl_acquire_lock_wait SIGNAL alter_go';
|
|
--echo # The below statement should get ER_LOCK_DEADLOCK error
|
|
--echo # (i.e. it should not allow ALTER to proceed, and then
|
|
--echo # fail due to 't1' changing its name to 't2').
|
|
--error ER_LOCK_DEADLOCK
|
|
update t1 set c3=c3+1 where c2 = 3;
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'con46273'.
|
|
connection con46273;
|
|
--echo # Reap ALTER TABLE.
|
|
--reap
|
|
|
|
--echo #
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
disconnect con46273;
|
|
--echo # Clean-up.
|
|
set debug_sync= 'RESET';
|
|
drop table t2;
|
|
|
|
|
|
--echo #
|
|
--echo # Test for bug #46673 "Deadlock between FLUSH TABLES WITH READ LOCK
|
|
--echo # and DML".
|
|
--echo #
|
|
--disable_warnings
|
|
drop tables if exists t1;
|
|
--enable_warnings
|
|
connect (con46673, localhost, root,,);
|
|
connection default;
|
|
create table t1 (i int);
|
|
|
|
--echo # Switching to connection 'con46673'.
|
|
connection con46673;
|
|
begin;
|
|
insert into t1 values (1);
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Statement below should not get blocked. And if after some
|
|
--echo # changes to code it is there should not be a deadlock between
|
|
--echo # it and transaction from connection 'con46673'.
|
|
flush tables with read lock;
|
|
unlock tables;
|
|
|
|
--echo # Switching to connection 'con46673'.
|
|
connection con46673;
|
|
delete from t1 where i = 1;
|
|
commit;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Clean-up
|
|
disconnect con46673;
|
|
drop table t1;
|
|
|
|
|
|
--echo #
|
|
--echo # Bug#48210 FLUSH TABLES WITH READ LOCK deadlocks
|
|
--echo # against concurrent CREATE PROCEDURE
|
|
--echo #
|
|
|
|
connect (con2, localhost, root);
|
|
|
|
--echo # Test 1: CREATE PROCEDURE
|
|
|
|
--echo # Connection 1
|
|
connection default;
|
|
--echo # Start CREATE PROCEDURE
|
|
SET DEBUG_SYNC= 'after_acquiring_mdl_lock_on_routine SIGNAL routine_locked WAIT_FOR grlwait';
|
|
--send CREATE PROCEDURE p1() SELECT 1
|
|
|
|
--echo # Connection 2
|
|
connection con2;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR routine_locked';
|
|
--echo # Check that FLUSH must wait to get the GRL
|
|
--echo # and let CREATE PROCEDURE continue
|
|
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait';
|
|
--send FLUSH TABLES WITH READ LOCK
|
|
|
|
--echo # Connection 1
|
|
connection default;
|
|
--reap
|
|
|
|
--echo # Connection 2
|
|
connection con2;
|
|
--reap
|
|
UNLOCK TABLES;
|
|
|
|
--echo # Connection 1
|
|
connection default;
|
|
SET DEBUG_SYNC= 'RESET';
|
|
|
|
--echo # Test 2: DROP PROCEDURE
|
|
|
|
connection default;
|
|
--echo # Start DROP PROCEDURE
|
|
SET DEBUG_SYNC= 'after_acquiring_mdl_lock_on_routine SIGNAL routine_locked WAIT_FOR grlwait';
|
|
--send DROP PROCEDURE p1
|
|
|
|
--echo # Connection 2
|
|
connection con2;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR routine_locked';
|
|
--echo # Check that FLUSH must wait to get the GRL
|
|
--echo # and let DROP PROCEDURE continue
|
|
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL grlwait';
|
|
--send FLUSH TABLES WITH READ LOCK
|
|
|
|
--echo # Connection 1
|
|
connection default;
|
|
--echo # Once FLUSH TABLES WITH READ LOCK starts waiting
|
|
--echo # DROP PROCEDURE will be waked up and will drop
|
|
--echo # procedure. Global read lock will be granted after
|
|
--echo # this statement ends.
|
|
--echo #
|
|
--echo # Reaping DROP PROCEDURE.
|
|
--reap
|
|
|
|
--echo # Connection 2
|
|
connection con2;
|
|
--echo # Reaping FTWRL.
|
|
--reap
|
|
UNLOCK TABLES;
|
|
|
|
--echo # Connection 1
|
|
connection default;
|
|
SET DEBUG_SYNC= 'RESET';
|
|
|
|
disconnect con2;
|
|
|
|
|
|
--echo #
|
|
--echo # Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null'
|
|
--echo # failed in open_ltable()
|
|
--echo #
|
|
|
|
--echo # Supress warnings written to the log file
|
|
call mtr.add_suppression("Wait on a lock was aborted due to a pending exclusive lock");
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1, t2;
|
|
--enable_warnings
|
|
|
|
connect (con1,localhost,root);
|
|
connect (con2,localhost,root);
|
|
connect (con3,localhost,root);
|
|
connection default;
|
|
|
|
CREATE TABLE t1 (i INT);
|
|
CREATE TABLE t2 (i INT);
|
|
|
|
SET @old_general_log= @@global.general_log;
|
|
SET @@global.general_log= 1;
|
|
|
|
SET @old_log_output= @@global.log_output;
|
|
SET @@global.log_output= 'TABLE';
|
|
|
|
SET @old_sql_log_off= @@session.sql_log_off;
|
|
SET @@session.sql_log_off= 1;
|
|
|
|
--echo # connection: con1
|
|
connection con1;
|
|
HANDLER t1 OPEN;
|
|
|
|
--echo # connection: con3
|
|
connection con3;
|
|
SET @@session.sql_log_off= 1;
|
|
|
|
--echo # connection: con2
|
|
connection con2;
|
|
SET DEBUG_SYNC= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
|
|
|
|
# The below statement will block on the debug sync point
|
|
# after it gets write lock on mysql.general_log table.
|
|
--echo # Sending:
|
|
--send SELECT 1
|
|
|
|
--echo # connection: con3
|
|
connection con3;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR parked';
|
|
|
|
--echo # connection: con1
|
|
connection con1;
|
|
# This statement will block in open_ltable() when
|
|
# trying to write into mysql.general_log.
|
|
--echo # Sending:
|
|
--send SELECT 1
|
|
|
|
--echo # connection: con3
|
|
connection con3;
|
|
let $wait_condition=
|
|
SELECT COUNT(*) = 1 FROM information_schema.processlist
|
|
WHERE state = "Waiting for table level lock" and info = "SELECT 1";
|
|
--source include/wait_condition.inc
|
|
# The ALTER below will try to abort the statement in connection con1,
|
|
# since the latter waits on a table-level lock while having a HANDLER
|
|
# open. This will cause mysql_lock_tables() in con1 fail which before
|
|
# triggered the assert.
|
|
ALTER TABLE t1 ADD COLUMN j INT;
|
|
|
|
--echo # connection: default
|
|
connection default;
|
|
SET DEBUG_SYNC= 'now SIGNAL go';
|
|
|
|
--echo # connection: con1
|
|
connection con1;
|
|
--echo # Reaping SELECT 1
|
|
--reap
|
|
HANDLER t1 CLOSE;
|
|
|
|
--echo # connection: con2
|
|
connection con2;
|
|
--echo # Reaping SELECT 1
|
|
--reap
|
|
|
|
--echo # connection: default
|
|
connection default;
|
|
DROP TABLE t1, t2;
|
|
SET DEBUG_SYNC= 'RESET';
|
|
disconnect con1;
|
|
disconnect con2;
|
|
disconnect con3;
|
|
SET @@global.general_log= @old_general_log;
|
|
SET @@global.log_output= @old_log_output;
|
|
SET @@session.sql_log_off= @old_sql_log_off;
|
|
|
|
|
|
--echo #
|
|
--echo # Additional coverage for bug #50913 "Deadlock between
|
|
--echo # open_and_lock_tables_derived and MDL". The main test
|
|
--echo # case is in lock_multi.test
|
|
--echo #
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
set debug_sync= 'RESET';
|
|
connect (con50913_1,localhost,root);
|
|
connect (con50913_2,localhost,root);
|
|
connection default;
|
|
create table t1 (i int) engine=InnoDB;
|
|
|
|
--echo # Switching to connection 'con50913_1'.
|
|
connection con50913_1;
|
|
set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL parked WAIT_FOR go';
|
|
--echo # Sending:
|
|
--send alter table t1 add column j int, ALGORITHM=COPY
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Wait until ALTER TABLE gets blocked on a sync point after
|
|
--echo # acquiring thr_lock.c lock.
|
|
set debug_sync= 'now WAIT_FOR parked';
|
|
--echo # The below statement should wait on MDL lock and not deadlock on
|
|
--echo # thr_lock.c lock.
|
|
--echo # Sending:
|
|
--send truncate table t1
|
|
|
|
--echo # Switching to connection 'con50913_2'.
|
|
connection con50913_2;
|
|
--echo # Wait until TRUNCATE TABLE is blocked on MDL lock.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "truncate table t1";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE.
|
|
set debug_sync= 'now SIGNAL go';
|
|
|
|
--echo # Switching to connection 'con50913_1'.
|
|
connection con50913_1;
|
|
--echo # Reaping ALTER TABLE.
|
|
--reap
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reaping TRUNCATE TABLE.
|
|
--reap
|
|
disconnect con50913_1;
|
|
disconnect con50913_2;
|
|
set debug_sync= 'RESET';
|
|
drop table t1;
|
|
|
|
|
|
--echo #
|
|
--echo # Test for bug #50998 "Deadlock in MDL code during test
|
|
--echo # rqg_mdl_stability".
|
|
--echo # Also provides coverage for the case when addition of
|
|
--echo # waiting statement adds several loops in the waiters
|
|
--echo # graph and therefore several searches for deadlock
|
|
--echo # should be performed.
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
set debug_sync= 'RESET';
|
|
connect (con1,localhost,root);
|
|
connect (con2,localhost,root);
|
|
connect (con3,localhost,root);
|
|
connection default;
|
|
create table t1 (i int);
|
|
|
|
--echo # Switching to connection 'con1'.
|
|
connection con1;
|
|
begin;
|
|
select * from t1;
|
|
|
|
--echo # Switching to connection 'con2'.
|
|
connection con2;
|
|
begin;
|
|
select * from t1;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Start ALTER TABLE which will acquire SNW lock and
|
|
--echo # table lock and get blocked on sync point.
|
|
set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL parked WAIT_FOR go';
|
|
--echo # Sending:
|
|
--send alter table t1 add column j int
|
|
|
|
--echo # Switching to connection 'con1'.
|
|
connection con1;
|
|
--echo # Wait until ALTER TABLE gets blocked on a sync point.
|
|
set debug_sync= 'now WAIT_FOR parked';
|
|
--echo # Sending:
|
|
--send insert into t1 values (1)
|
|
|
|
--echo # Switching to connection 'con2'.
|
|
connection con2;
|
|
--echo # Sending:
|
|
--send insert into t1 values (1)
|
|
|
|
--echo # Switching to connection 'con3'.
|
|
connection con3;
|
|
--echo # Wait until both 'con1' and 'con2' are blocked trying to acquire
|
|
--echo # SW lock on the table.
|
|
let $wait_condition=
|
|
select count(*) = 2 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "insert into t1 values (1)";
|
|
--source include/wait_condition.inc
|
|
--echo # Unblock ALTER TABLE. Since it will try to upgrade SNW to X lock
|
|
--echo # deadlock with two loops in waiting graph will occur. Both loops
|
|
--echo # should be found and DML statements in both 'con1' and 'con2'
|
|
--echo # should be aborted with ER_LOCK_DEADLOCK errors.
|
|
set debug_sync= 'now SIGNAL go';
|
|
|
|
--echo # Switching to connection 'con1'.
|
|
connection con1;
|
|
--echo # Reaping INSERT. It should end with ER_LOCK_DEADLOCK error and
|
|
--echo # not wait indefinitely (as it happened before the bugfix).
|
|
--error ER_LOCK_DEADLOCK
|
|
--reap
|
|
commit;
|
|
|
|
--echo # Switching to connection 'con2'.
|
|
connection con2;
|
|
--echo # Reaping INSERT.
|
|
--error ER_LOCK_DEADLOCK
|
|
--reap
|
|
commit;
|
|
|
|
--echo # Switching to connection 'default'.
|
|
connection default;
|
|
--echo # Reap ALTER TABLE.
|
|
--reap
|
|
|
|
disconnect con1;
|
|
disconnect con2;
|
|
disconnect con3;
|
|
connection default;
|
|
set debug_sync= 'RESET';
|
|
drop table t1;
|
|
|
|
--echo #
|
|
--echo # Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
|
|
--echo #
|
|
--echo # Ensure that a acquired lock is not given up due to a conflict.
|
|
--echo #
|
|
|
|
connect (con1,localhost,root,,test,,);
|
|
connect (con2,localhost,root,,test,,);
|
|
connect (con3,localhost,root,,test,,);
|
|
|
|
connection default;
|
|
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1;
|
|
--enable_warnings
|
|
|
|
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
|
INSERT INTO t1 VALUES (1),(2),(3);
|
|
|
|
--echo # Connection: con1
|
|
connection con1;
|
|
LOCK TABLES t1 WRITE;
|
|
SET debug_sync='upgrade_lock_for_truncate SIGNAL parked_truncate WAIT_FOR go_truncate';
|
|
send TRUNCATE TABLE t1;
|
|
|
|
connection default;
|
|
--echo # Connection: default
|
|
SET debug_sync='now WAIT_FOR parked_truncate';
|
|
|
|
connection con2;
|
|
--echo # Connection: con2
|
|
SET debug_sync='after_acquiring_mdl_shared_to_fetch_stats SIGNAL parked_show WAIT_FOR go_show';
|
|
--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
|
|
|
|
connection default;
|
|
--echo # Connection: default
|
|
SET debug_sync='now WAIT_FOR parked_show';
|
|
|
|
connection con3;
|
|
--echo # Connection: con3
|
|
SET debug_sync='after_flush_unlock SIGNAL parked_flush WAIT_FOR go_flush';
|
|
send FLUSH TABLES t1;
|
|
|
|
connection default;
|
|
--echo # Connection: default
|
|
SET debug_sync='now WAIT_FOR parked_flush';
|
|
SET debug_sync='now SIGNAL go_truncate';
|
|
--echo # Ensure that truncate waits for a exclusive lock
|
|
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
|
|
WHERE state='Waiting for table metadata lock' AND info='TRUNCATE TABLE t1';
|
|
--source include/wait_condition.inc
|
|
SET debug_sync= 'now SIGNAL go_show';
|
|
|
|
connection con1;
|
|
--echo # Connection: con1 (TRUNCATE)
|
|
--echo # Reaping...
|
|
reap;
|
|
UNLOCK TABLES;
|
|
|
|
connection con2;
|
|
--echo # Connection: con2 (SHOW FIELDS FROM t1)
|
|
--echo # Reaping...
|
|
reap;
|
|
|
|
connection default;
|
|
--echo # Connection: default
|
|
SET debug_sync= 'now SIGNAL go_flush';
|
|
|
|
connection con3;
|
|
--echo # Connection: con3 (FLUSH TABLES t1)
|
|
--echo # Reaping...
|
|
reap;
|
|
|
|
disconnect con1;
|
|
disconnect con2;
|
|
disconnect con3;
|
|
|
|
connection default;
|
|
--echo # Connection: default
|
|
SET debug_sync= 'RESET';
|
|
DROP TABLE t1;
|
|
|
|
|
|
--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 schema metadata lock' 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 schema metadata lock'
|
|
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 schema metadata lock' 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 # 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 schema metadata lock' 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 schema metadata lock'
|
|
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 ER_NO_SUCH_DB
|
|
--reap
|
|
|
|
|
|
--echo # Test 4:
|
|
--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 schema metadata lock' 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 5:
|
|
--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 schema metadata lock' 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_BAD_DB_ERROR
|
|
--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 schema metadata lock' 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 ER_BAD_DB_ERROR
|
|
--reap
|
|
DROP TABLE test.t2;
|
|
|
|
|
|
--echo # Test 6:
|
|
--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 schema metadata lock' 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 global read lock'
|
|
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 global read lock'
|
|
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;
|
|
|
|
|
|
--echo #
|
|
--echo # Bug#56292 Deadlock with ALTER TABLE and MERGE tables
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1, t2, m1;
|
|
--enable_warnings
|
|
|
|
CREATE TABLE t1(a INT) engine=MyISAM;
|
|
CREATE TABLE t2(a INT) engine=MyISAM;
|
|
CREATE TABLE m1(a INT) engine=MERGE UNION=(t1, t2);
|
|
|
|
INSERT INTO t1 VALUES (1), (2);
|
|
INSERT INTO t2 VALUES (3), (4);
|
|
|
|
connect(con1, localhost, root);
|
|
connect(con2, localhost, root);
|
|
|
|
--echo # Connection con1
|
|
connection con1;
|
|
--echo # We need EXECUTE 2 since ALTER TABLE does SU => SNW => X and we want
|
|
--echo # to stop at the second upgrade.
|
|
SET DEBUG_SYNC= 'mdl_upgrade_lock SIGNAL upgrade WAIT_FOR continue EXECUTE 2';
|
|
--echo # Sending:
|
|
--send ALTER TABLE m1 engine=MERGE UNION=(t2, t1)
|
|
|
|
--echo # Connection con2
|
|
connection con2;
|
|
--echo # Waiting for ALTER TABLE to try lock upgrade
|
|
SET DEBUG_SYNC= 'now WAIT_FOR upgrade';
|
|
SET DEBUG_SYNC= 'now SIGNAL continue';
|
|
SET DEBUG_SYNC= 'now WAIT_FOR upgrade';
|
|
--echo # Sending:
|
|
--send DELETE FROM t2 WHERE a = 3
|
|
|
|
--echo # Connection default
|
|
connection default;
|
|
--echo # Check that DELETE is waiting on a metadata lock and not a table lock.
|
|
let $wait_condition=
|
|
SELECT COUNT(*) = 1 FROM information_schema.processlist
|
|
WHERE state = "Waiting for table metadata lock" AND
|
|
info = "DELETE FROM t2 WHERE a = 3";
|
|
--source include/wait_condition.inc
|
|
--echo # Now that DELETE blocks on a metadata lock, we should be able to do
|
|
--echo # SELECT * FROM m1 here. SELECT used to be blocked by a DELETE table
|
|
--echo # lock request.
|
|
SELECT * FROM m1;
|
|
--echo # Resuming ALTER TABLE
|
|
SET DEBUG_SYNC= 'now SIGNAL continue';
|
|
|
|
--echo # Connection con1
|
|
connection con1;
|
|
--echo # Reaping: ALTER TABLE m1 engine=MERGE UNION=(t2, t1)
|
|
--reap
|
|
--echo # Connection con2
|
|
connection con2;
|
|
--echo # Reaping: DELETE FROM t2 WHERE a = 3
|
|
--reap
|
|
--echo # Connection default
|
|
connection default;
|
|
DROP TABLE m1, t1, t2;
|
|
SET DEBUG_SYNC= 'RESET';
|
|
disconnect con1;
|
|
disconnect con2;
|
|
|
|
|
|
--echo #
|
|
--echo # Bug#21021848 ASSERTION `M_STATUS == DA_ERROR' FAILED.
|
|
--echo #
|
|
CREATE TABLE t1(c1 INT NOT NULL) ENGINE = csv;
|
|
CREATE TABLE t2(c1 INT NOT NULL);
|
|
|
|
--echo # Emulate corruption of t1
|
|
LOCK TABLES t1 WRITE;
|
|
INSERT INTO t1 VALUES(0);
|
|
CHECK TABLE t1;
|
|
UNLOCK TABLES;
|
|
|
|
--echo # Start XA txn on default
|
|
XA START 'test2';
|
|
--echo # Acquire SR on t2
|
|
SELECT * FROM t2;
|
|
--echo # Block IS query just before calling lock_table_names() (before X on t1)
|
|
SET DEBUG_SYNC='recover_ot_repair SIGNAL parked WAIT_FOR go';
|
|
--send select table_name, table_type, auto_increment, table_comment from information_schema.tables where table_schema='test' and table_name='t1';
|
|
|
|
--echo # Create a new conncection which will compete for MDL lock
|
|
--connect (con1,localhost,root,,)
|
|
--echo # Wait until default becomes blocked
|
|
SET DEBUG_SYNC='now WAIT_FOR parked';
|
|
--echo # Try to acquire X on t1 and t2, which will block while default
|
|
--echo # holds SR on t2
|
|
--send DROP TABLES t1, t2
|
|
|
|
--echo # Create control connection
|
|
--connect (con2,localhost,root,,)
|
|
|
|
--echo # Wait until con1 is blocked
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "DROP TABLES t1, t2";
|
|
--source include/wait_condition.inc
|
|
--echo # Wake up XA txn/IS query on default
|
|
SET DEBUG_SYNC='now SIGNAL go';
|
|
--echo # Disconnect control connection
|
|
--disconnect con2
|
|
--source include/wait_until_disconnected.inc
|
|
|
|
--echo # Switch to default connection
|
|
--connection default
|
|
--echo # Wait for IS query which will try repair t1 which requires X.
|
|
--echo # Previously that resulted in deadlock with con1 over t1,
|
|
--echo # but now t1 is skipped and a warning is issued
|
|
--reap
|
|
|
|
--echo # Finish XA txn 'test2' to release SR on t2 so that con1
|
|
--echo # becomes unblocked
|
|
XA END 'test2';
|
|
XA PREPARE 'test2';
|
|
XA COMMIT 'test2';
|
|
|
|
--echo # Cleanup
|
|
SET DEBUG_SYNC= 'RESET';
|
|
|
|
--echo # Clean up con1 now that the XA txn has finished
|
|
--connection con1
|
|
--echo # Wait for the now unblocked DROP t1, t2 to complete
|
|
--reap
|
|
--echo # Disconnecting con1
|
|
--disconnect con1
|
|
--source include/wait_until_disconnected.inc
|
|
|
|
--echo # Switching to back to default at end of test case
|
|
--connection default
|
|
|
|
--echo #
|
|
--echo # Bug#26739438 DEADLOCK ON GET_LOCK(..., 0)
|
|
--echo #
|
|
--echo # Run GET_LOCK(...,0) from two connections to which would previously
|
|
--echo # cause deadlock
|
|
|
|
CREATE TABLE t1(i INT);
|
|
INSERT INTO t1 VALUES (0), (1);
|
|
|
|
--echo # Starting con0
|
|
connect (con0,localhost,root,,test,,);
|
|
SELECT i FROM t1 WHERE i = 0 AND GET_LOCK(i, 0);
|
|
|
|
--echo # Starting con1
|
|
connect (con1,localhost,root,,test,,);
|
|
SELECT i FROM t1 WHERE i = 1 AND GET_LOCK(i, 0);
|
|
|
|
--echo # Send query which will do a 0-wait on i=0 while holding lock on i=1
|
|
SET DEBUG_SYNC='mdl_acquire_lock_wait SIGNAL wait0 WAIT_FOR go0';
|
|
--send SELECT i FROM t1 WHERE GET_LOCK(i, 0) AND i = 0
|
|
|
|
--echo # Switch to con0. Send query which will do a 0-wait on i=1 while
|
|
--echo # holding lock on i=0
|
|
connection con0;
|
|
SET DEBUG_SYNC='mdl_acquire_lock_wait SIGNAL wait1 WAIT_FOR go1';
|
|
--send SELECT i FROM t1 WHERE GET_LOCK(i, 0) AND i = 1
|
|
|
|
--echo # Switch to default connection and wait until both con0 and con1
|
|
--echo # are ready to check for deadlocks
|
|
connection default;
|
|
SET DEBUG_SYNC='now WAIT_FOR wait0';
|
|
SET DEBUG_SYNC='now WAIT_FOR wait1';
|
|
|
|
--echo # Tell both connections to proceed
|
|
SET DEBUG_SYNC='now SIGNAL go0';
|
|
SET DEBUG_SYNC='now SIGNAL go1';
|
|
|
|
--echo # Wait for con0
|
|
connection con0;
|
|
--reap
|
|
|
|
--echo # Wait for con1 (should not deadlock)
|
|
connection con1;
|
|
--reap
|
|
|
|
connection default;
|
|
disconnect con0;
|
|
disconnect con1;
|
|
|
|
DROP TABLE t1;
|
|
|
|
--echo #
|
|
--echo # Bug#26770836 SLAVE HANGS - WAITING FOR TABLE METADATA LOCKS
|
|
--echo # Check that ALTER TABLE will not release MDL locks that were
|
|
--echo # acquired during view metadata update, until end of statement.
|
|
--echo #
|
|
|
|
SET DEBUG_SYNC= 'RESET';
|
|
CREATE TABLE t1 (f1 INT, f2 INT);
|
|
CREATE TABLE t2 (g1 INT, g2 INT);
|
|
CREATE VIEW v1 AS SELECT f2 FROM t1, t2;
|
|
|
|
connect (con1,localhost,root,,);
|
|
connection con1;
|
|
SET DEBUG_SYNC= 'after_updating_view_metadata SIGNAL
|
|
after_view_update WAIT_FOR continue_alter';
|
|
|
|
--echo # Run ALTER TABLE until after the view metadata is updated.
|
|
--send ALTER TABLE t1 DROP COLUMN f2
|
|
|
|
connect (con2,localhost,root,,);
|
|
connection con2;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR after_view_update';
|
|
|
|
--echo # Run REPAIR which tries to acquire MDL X on t2, and expect it to wait.
|
|
--send REPAIR TABLE t2;
|
|
|
|
connection default;
|
|
--echo # The wait_condition makes sure that the lock on table t2 is
|
|
--echo # held by ALTER TABLE after updating view metadata. Wait condition
|
|
--echo # fails if run without the fix.
|
|
let $wait_condition=
|
|
select count(*) = 1 from information_schema.processlist
|
|
where state = "Waiting for table metadata lock" and
|
|
info = "REPAIR TABLE t2";
|
|
--source include/wait_condition.inc
|
|
|
|
SET DEBUG_SYNC= 'now SIGNAL continue_alter';
|
|
|
|
connection con1;
|
|
--reap
|
|
|
|
connection con2;
|
|
--reap
|
|
|
|
--echo # cleanup
|
|
connection default;
|
|
|
|
disconnect con2;
|
|
disconnect con1;
|
|
|
|
DROP VIEW v1;
|
|
DROP TABLE t1;
|
|
DROP TABLE t2;
|
|
|
|
# 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
|
|
|