# This tests Bug#16986 Deadlock condition with MyISAM tables # All tests are required to run with Myisam. # Hence MTR starts mysqld with MyISAM as default --source include/force_myisam_default.inc --source include/have_myisam.inc # Save the initial number of concurrent sessions --source include/count_sessions.inc --disable_warnings drop table if exists t1,t2; --enable_warnings # Test to see if select will get the lock ahead of low priority update connect (locker,localhost,root,,); connect (locker2,localhost,root,,); connect (reader,localhost,root,,); connect (writer,localhost,root,,); connection locker; create table t1(n int); insert into t1 values (1); connection locker2; select get_lock("mysqltest_lock", 100); connection locker; send update t1 set n = 2 and get_lock('mysqltest_lock', 100); connection writer; # Wait till above update gets blocked on a user lock. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "update t1 set n = 2 and get_lock('mysqltest_lock', 100)"; --source include/wait_condition.inc send update low_priority t1 set n = 4; connection reader; # Sleep a bit till the update of connection writer is in work and hangs let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and info = "update low_priority t1 set n = 4"; --source include/wait_condition.inc send select n from t1; connection locker2; # Sleep a bit till the select of connection reader is in work and hangs let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and info = "select n from t1"; --source include/wait_condition.inc select release_lock("mysqltest_lock"); connection locker; reap; select release_lock("mysqltest_lock"); connection writer; reap; connection reader; reap; drop table t1; connection locker; create table t1(n int); insert into t1 values (1); connection locker2; select get_lock("mysqltest_lock", 100); connection locker; send select n from t1 where get_lock('mysqltest_lock', 100); connection writer; # Wait till above select gets blocked on a user lock. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "select n from t1 where get_lock('mysqltest_lock', 100)"; --source include/wait_condition.inc send update low_priority t1 set n = 4; connection reader; # Sleep a bit till the update of connection writer is in work and hangs let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and info = "update low_priority t1 set n = 4"; --source include/wait_condition.inc select n from t1; connection locker2; select release_lock("mysqltest_lock"); connection locker; reap; select release_lock("mysqltest_lock"); connection writer; reap; drop table t1; --echo # --echo # Test locking in multi-update statements. --echo # --echo # --echo # Multi-update should not be blocked by THR_LOCK locks acquired --echo # on table which is not updated. --echo # --enable_connect_log connection locker; create table t1 (a int, b int); create table t2 (c int, d int); insert into t1 values(1,1); insert into t1 values(2,2); insert into t2 values(1,2); connection locker2; select get_lock("mysqltest_lock", 100); connection locker; --echo # Sending: --send select a from t1 where get_lock('mysqltest_lock', 100) connection writer; --echo # Wait till above select gets blocked on a user lock. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "select a from t1 where get_lock('mysqltest_lock', 100)"; --source include/wait_condition.inc update t1,t2 set c=a where b=d; connection reader; select c from t2; connection locker2; select release_lock("mysqltest_lock"); connection locker; --echo # Reap select. --reap select release_lock("mysqltest_lock"); --echo # --echo # Indeed it should be blocked by THR_LOCK locks on table --echo # which is updated. --echo # connection locker2; select get_lock("mysqltest_lock", 100); connection locker; --echo # Sending: --send select c from t2 where get_lock('mysqltest_lock', 100) connection writer; --echo # Wait till above select gets blocked on a user lock. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "select c from t2 where get_lock('mysqltest_lock', 100)"; --source include/wait_condition.inc --echo # Sending: --send update t1,t2 set c=a where b=d; connection default; --echo # Wait till multi-update is blocked on THR_LOCK lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and info = "update t1,t2 set c=a where b=d"; connection locker2; select release_lock("mysqltest_lock"); connection locker; --echo # Reap select. --reap select release_lock("mysqltest_lock"); connection writer; --echo # Reap multi-update. --reap --echo # --echo # OTOH multi-update will be blocked by concurrent LOCK TABLES READ --echo # on any table in the join. This is because multi-update acquires --echo # SW metadata locks on all tables in the join which conflicts with --echo # SRO metadata lock acquired by LOCK TABLES READ. --echo # connection locker; lock table t1 read; connection writer; --echo # Sending: --send update t1,t2 set c=a where b=d; connection default; --echo # Wait till multi-update is blocked on THR_LOCK lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "update t1,t2 set c=a where b=d"; connection locker; unlock tables; connection writer; --echo # Reap multi-update. --reap connection locker; lock table t2 read; connection writer; --echo # Sending: --send update t1,t2 set c=a where b=d; connection default; --echo # Wait till multi-update is blocked on THR_LOCK lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "update t1,t2 set c=a where b=d"; connection locker; unlock tables; connection writer; --echo # Reap multi-update. --reap --echo # --echo # Still if multi-update is executed under LOCK TABLES --echo # it will be compatible with LOCK TABLES READ on the --echo # table from its join which is only read. --echo # --echo # Main difference here is that LOCK TABLES preannounces --echo # locks which will be requested by multi-update. --echo # connection locker; lock table t1 read; connection writer; lock tables t1 read, t2 write; update t1,t2 set c=a where b=d; unlock tables; connection locker; unlock tables; connection default; drop table t1; drop table t2; --disable_connect_log # # Test problem when using locks on many tables and dropping a table that # is to-be-locked by another thread # # connection locker; create table t1 (a int); create table t2 (a int); lock table t1 write, t2 write; connection reader; send insert t1 select * from t2; connection locker; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "insert t1 select * from t2"; --source include/wait_condition.inc drop table t2; unlock tables; connection reader; --error ER_NO_SUCH_TABLE reap; connection locker; drop table t1; # # Same test as above, but with the dropped table locked twice # connection locker; create table t1 (a int); create table t2 (a int); lock table t1 write, t2 write, t1 as t1_2 write, t2 as t2_2 write; connection reader; send insert t1 select * from t2; connection locker; # Sleep a bit till the insert of connection reader is in work and hangs let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "insert t1 select * from t2"; --source include/wait_condition.inc drop table t2; unlock tables; connection reader; --error ER_NO_SUCH_TABLE reap; connection locker; drop table t1; --echo End of 4.1 tests # # Bug#9998 MySQL client hangs on USE "database" # create table t1(a int); lock tables t1 write; connection reader; show columns from t1; connection locker; unlock tables; drop table t1; # # Bug#16986 Deadlock condition with MyISAM tables # # Need a matching user in mysql.user for multi-table select --source include/add_anonymous_users.inc connection locker; USE mysql; LOCK TABLES columns_priv WRITE, db WRITE, user WRITE; FLUSH TABLES; # connection reader; USE mysql; # Note: This must be a multi-table select, otherwise the deadlock will not occur send SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1; # connection locker; # Sleep a bit till the select of connection reader is in work and hangs let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = "Waiting for table metadata lock" AND info = "SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1"; --source include/wait_condition.inc # Make test case independent from earlier grants. --replace_result "Table is already up to date" "OK" OPTIMIZE TABLES columns_priv, db, user; UNLOCK TABLES; # connection reader; reap; USE test; # connection locker; use test; # connection default; # # Test if CREATE TABLE with LOCK TABLE deadlocks. # connection writer; CREATE TABLE t1 (c1 int); LOCK TABLE t1 WRITE; # # This waits until t1 is unlocked. connection locker; send FLUSH TABLES WITH READ LOCK; # connection writer; # Sleep a bit till the flush of connection locker is in work and hangs let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "FLUSH TABLES WITH READ LOCK"; --source include/wait_condition.inc # This must not block. --error ER_TABLE_NOT_LOCKED CREATE TABLE t2 (c1 int); UNLOCK TABLES; # # This awakes now. connection locker; reap; UNLOCK TABLES; # connection default; DROP TABLE t1; # # Test if CREATE TABLE SELECT with LOCK TABLE deadlocks. # connection writer; CREATE TABLE t1 (c1 int); LOCK TABLE t1 WRITE; # # This waits until t1 is unlocked. connection locker; send FLUSH TABLES WITH READ LOCK; # # This must not block. connection writer; # Sleep a bit till the flush of connection locker is in work and hangs let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "FLUSH TABLES WITH READ LOCK"; --source include/wait_condition.inc --error ER_TABLE_NOT_LOCKED CREATE TABLE t2 AS SELECT * FROM t1; UNLOCK TABLES; # # This awakes now. connection locker; reap; UNLOCK TABLES; # connection default; DROP TABLE t1; --source include/delete_anonymous_users.inc # # Bug#19815 CREATE/RENAME/DROP DATABASE can deadlock on a global read lock # connect (con1,localhost,root,,); connect (con2,localhost,root,,); # connection con1; CREATE DATABASE mysqltest_1; FLUSH TABLES WITH READ LOCK; # # With bug in place: acquire LOCK_mysql_create_table and # wait in wait_if_global_read_lock(). connection con2; send DROP DATABASE mysqltest_1; # # With bug in place: try to acquire LOCK_mysql_create_table... # When fixed: Reject dropping db because of the read lock. connection con1; # Wait a bit so that the session con2 is in state # "Waiting for global read lock" let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "DROP DATABASE mysqltest_1"; --source include/wait_condition.inc --error ER_CANT_UPDATE_WITH_READLOCK DROP DATABASE mysqltest_1; UNLOCK TABLES; # connection con2; reap; # connection default; disconnect con1; disconnect con2; # This must have been dropped by connection 2 already, # which waited until the global read lock was released. --error ER_DB_DROP_EXISTS DROP DATABASE mysqltest_1; # # Bug#17264 MySQL Server freeze # connection locker; # Disable warnings to allow test to run also without InnoDB --disable_warnings create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb; --enable_warnings lock tables t1 write; connection writer; send alter table t1 auto_increment=0; connection reader; # Wait till connection writer is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "alter table t1 auto_increment=0"; --source include/wait_condition.inc send alter table t1 auto_increment=0; connection locker; # Wait till connection reader is blocked let $wait_condition= select count(*) = 2 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "alter table t1 auto_increment=0"; --source include/wait_condition.inc unlock tables; connection writer; reap; connection reader; reap; connection locker; drop table t1; # # Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely # connect (con1,localhost,root,,); connect (con2,localhost,root,,); connect (con3,localhost,root,,); connect (con4,localhost,root,,); connect (con5,localhost,root,,); create table t1 (a int); create table t2 like t1; connection con1; --echo # con1 lock tables t1 write; connection con2; --echo # con2 send flush tables with read lock; connection con5; --echo # con5 let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "flush tables with read lock"; --source include/wait_condition.inc --echo # global read lock is taken connection con3; --echo # con3 send select * from t2 for update; connection con5; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "select * from t2 for update"; --source include/wait_condition.inc --echo # waiting for release of read lock connection con4; --echo # con4 --echo # would hang and later cause a deadlock flush tables t2; connection con1; --echo # clean up unlock tables; connection con2; --reap unlock tables; connection con3; --reap connection default; disconnect con5; disconnect con4; disconnect con3; disconnect con2; disconnect con1; drop table t1,t2; --echo # --echo # Lightweight version: --echo # Ensure that the wait for a GRL is done before opening tables. --echo # connect (con1,localhost,root,,); connect (con2,localhost,root,,); create table t1 (a int); create table t2 like t1; --echo # --echo # UPDATE --echo # connection default; --echo # default flush tables with read lock; connection con1; --echo # con1 send update t2 set a = 1; connection default; --echo # default let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "update t2 set a = 1"; --source include/wait_condition.inc --echo # statement is waiting for release of read lock connection con2; --echo # con2 flush table t2; connection default; --echo # default unlock tables; connection con1; --echo # con1 --reap --echo # --echo # LOCK TABLES .. WRITE --echo # connection default; --echo # default flush tables with read lock; connection con1; --echo # con1 send lock tables t2 write; connection default; --echo # default let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "lock tables t2 write"; --source include/wait_condition.inc --echo # statement is waiting for release of read lock connection con2; --echo # con2 flush table t2; connection default; --echo # default unlock tables; connection con1; --echo # con1 --reap unlock tables; connection default; disconnect con2; disconnect con1; drop table t1,t2; --echo End of 5.0 tests # # Bug#21281 Pending write lock is incorrectly removed when its # statement being KILLed # create table t1 (i int); insert into t1 values (1); select get_lock('mysqltest_lock', 100); connection locker; send select * from t1 where get_lock('mysqltest_lock', 100); connection writer; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "select * from t1 where get_lock('mysqltest_lock', 100)"; --source include/wait_condition.inc send update t1 set i= 10; connection reader; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and info = "update t1 set i= 10"; --source include/wait_condition.inc send select * from t1; connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and info = "select * from t1"; --source include/wait_condition.inc let $ID= `select id from information_schema.processlist where state = "Waiting for table level lock" and info = "update t1 set i= 10"`; --replace_result $ID ID eval kill query $ID; connection reader; --reap connection writer; --error ER_QUERY_INTERRUPTED --reap connection default; select release_lock('mysqltest_lock'); connection locker; --reap select release_lock('mysqltest_lock'); connection default; drop table t1; # # Bug#25856 HANDLER table OPEN in one connection lock DROP TABLE in another one # --disable_warnings drop table if exists t1; --enable_warnings create table t1 (a int) ENGINE=MEMORY; --echo --> client 2 connection locker; --error ER_ILLEGAL_HA handler t1 open; --echo --> client 1 connection default; drop table t1; # Disconnect sessions used in many subtests above disconnect locker; disconnect locker2; disconnect reader; disconnect writer; # # Bug#32395 Alter table under a impending global read lock causes a server crash # # # Test ALTER TABLE under LOCK TABLES and FLUSH TABLES WITH READ LOCK # --disable_warnings drop table if exists t1; --enable_warnings create table t1 (i int); connect (flush,localhost,root,,test,,); connection default; --echo connection: default lock tables t1 write; connection flush; --echo connection: flush --send flush tables with read lock; connection default; --echo connection: default let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "flush tables with read lock"; --source include/wait_condition.inc alter table t1 add column j int; connect (insert,localhost,root,,test,,); connection insert; --echo connection: insert let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "flush tables with read lock"; --source include/wait_condition.inc --send insert into t1 values (1,2); --echo connection: default connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "insert into t1 values (1,2)"; --source include/wait_condition.inc unlock tables; connection flush; --echo connection: flush --reap let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock" and info = "insert into t1 values (1,2)"; --source include/wait_condition.inc select * from t1; unlock tables; connection insert; --reap connection default; let $wait_condition= select count(*) = 1 from t1; --source include/wait_condition.inc select * from t1; drop table t1; disconnect flush; disconnect insert; # # Test that FLUSH TABLES under LOCK TABLES protects write locked tables # from a impending FLUSH TABLES WITH READ LOCK # --disable_warnings drop table if exists t1; --enable_warnings create table t1 (i int); connect (flush,localhost,root,,test,,); connection default; --echo connection: default lock tables t1 write; connection flush; --echo connection: flush --send flush tables with read lock; connection default; --echo connection: default let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock"; --source include/wait_condition.inc flush tables; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock"; --source include/wait_condition.inc unlock tables; connection flush; --reap connection default; disconnect flush; drop table t1; # # Bug#30331 Table_locks_waited shows inaccurate values # --disable_warnings drop table if exists t1,t2; --enable_warnings create table t1 (a int); insert into t1 values (1); connect (blocker,localhost,root,,); connection blocker; select get_lock('mysqltest_lock', 100); connection default; flush status; send select * from t1 where get_lock('mysqltest_lock', 100); connect (waiter,localhost,root,,); connection waiter; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "select * from t1 where get_lock('mysqltest_lock', 100)"; --source include/wait_condition.inc let $tlwa= `show status like 'Table_locks_waited'`; send update t1 set a= 2; connection blocker; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and info = "update t1 set a= 2"; --source include/wait_condition.inc let $tlwb= `show status like 'Table_locks_waited'`; select release_lock('mysqltest_lock'); connection waiter; --reap connection default; --reap select release_lock('mysqltest_lock'); drop table t1; disconnect blocker; disconnect waiter; --disable_query_log eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1); eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1); --enable_query_log select @tlwa < @tlwb; --echo End of 5.1 tests # # Test that DROP TABLES does not wait for a impending FLUSH TABLES # WITH READ LOCK # --disable_warnings drop table if exists t1; --enable_warnings create table t1 (i int); connect (flush,localhost,root,,test,,); connection default; --echo connection: default lock tables t1 write; connection flush; --echo connection: flush --send flush tables with read lock; connection default; --echo connection: default let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock"; --source include/wait_condition.inc flush tables; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for global read lock"; --source include/wait_condition.inc drop table t1; connection flush; --reap connection default; disconnect flush; --echo # --echo # Test for bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock". --echo # --disable_warnings drop table if exists t1; --enable_warnings 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; update t1 set c3=c3+1 where c2=3; --echo # --echo # Switching to connection 'con46272'. connect (con46272,localhost,root,,test,,); connection con46272; --echo # The below ALTER TABLE statement should wait till transaction --echo # in connection 'default' is complete and then succeed. --echo # It should not deadlock or fail with ER_LOCK_DEADLOCK error. --echo # Sending: --send alter table t1 add column c4 int; --echo # --echo # Switching to connection 'default'. connection default; --echo # Wait until the above ALTER TABLE gets blocked because this --echo # connection holds SW metadata lock on table to be altered. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "alter table t1 add column c4 int"; --source include/wait_condition.inc --echo # The below statement should succeed. It should not --echo # deadlock or end with ER_LOCK_DEADLOCK error. update t1 set c3=c3+1 where c2=4; --echo # Unblock ALTER TABLE by committing transaction. commit; --echo # --echo # Switching to connection 'con46272'. connection con46272; --echo # Reaping ALTER TABLE. --reap --echo # --echo # Switching to connection 'default'. connection default; disconnect con46272; drop table t1; --echo # --echo # Bug#47249 assert in MDL_global_lock::is_lock_type_compatible --echo # --disable_warnings DROP TABLE IF EXISTS t1; DROP VIEW IF EXISTS v1; --enable_warnings --echo # --echo # Test 1: LOCK TABLES v1 WRITE, t1 READ; --echo # --echo # Thanks to the fact that we no longer allow DDL on tables --echo # which are locked for write implicitly, the exact scenario --echo # in which assert was failing is no longer repeatable. CREATE TABLE t1 ( f1 integer ); CREATE VIEW v1 AS SELECT f1 FROM t1 ; --echo # Connection 2 connect (con2,localhost,root); LOCK TABLES v1 WRITE, t1 READ; FLUSH TABLE t1; disconnect con2; --source include/wait_until_disconnected.inc --echo # Connection 1 connection default; LOCK TABLES t1 WRITE; FLUSH TABLE t1; # Assertion happened here UNLOCK TABLES; # Cleanup DROP TABLE t1; DROP VIEW v1; --echo # --echo # Test 2: LOCK TABLES t1 WRITE, v1 READ; --echo # CREATE TABLE t1 ( f1 integer ); CREATE VIEW v1 AS SELECT f1 FROM t1 ; --echo # Connection 2 connect (con2,localhost,root); LOCK TABLES t1 WRITE, v1 READ; FLUSH TABLE t1; disconnect con2; --source include/wait_until_disconnected.inc --echo # Connection 1 connection default; LOCK TABLES t1 WRITE; FLUSH TABLE t1; # Assertion happened here # Cleanup DROP TABLE t1; DROP VIEW v1; --echo # --echo # Test for bug #50913 "Deadlock between open_and_lock_tables_derived --echo # and MDL". Also see additional coverage in mdl_sync.test. --echo # --disable_warnings drop table if exists t1; drop view if exists v1; --enable_warnings connect (con50913,localhost,root); connection default; create table t1 (i int); create view v1 as select i from t1; begin; select * from t1; --echo # Switching to connection 'con50913'. connection con50913; --echo # Sending: --send alter table t1 add column j int --echo # Switching to connection 'default'. connection default; --echo # Wait until ALTER TABLE gets blocked. 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 # The below statement should try to acquire SW lock on 't1' --echo # and therefore should get ER_LOCK_DEADLOCK error. Before --echo # bug fix it acquired SR lock and hung on thr_lock.c lock. --error ER_LOCK_DEADLOCK delete a from t1 as a where i = 1; --echo # Unblock ALTER TABLE. commit; --echo # Switching to connection 'con50913'. connection con50913; --echo # Reaping ALTER TABLE; --reap --echo # Switching to connection 'default'. connection default; begin; select * from v1; --echo # Switching to connection 'con50913'. connection con50913; --echo # Sending: --send alter table t1 drop column j --echo # Switching to connection 'default'. connection default; --echo # Wait until ALTER TABLE gets 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 # The below statement should try to acquire SW lock on 't1' --echo # and therefore should get ER_LOCK_DEADLOCK error. Before --echo # bug fix it acquired SR lock and hung on thr_lock.c lock. --error ER_LOCK_DEADLOCK insert into v1 values (1); --echo # Unblock ALTER TABLE. commit; --echo # Switching to connection 'con50913'. connection con50913; --echo # Reaping ALTER TABLE; --reap --echo # Switching to connection 'default'. connection default; disconnect con50913; drop view v1; drop table t1; --echo # --echo # Bug#45225 Locking: hang if drop table with no timeout --echo # --echo # These tests also provide function coverage for the --echo # lock_wait_timeout server variable. --echo # --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings CREATE TABLE t1 (id int); connect(con2, localhost, root,,); SET SESSION lock_wait_timeout= 1; --echo # --echo # Test 1: acquire exclusive lock --echo # --echo # Connection default connection default; START TRANSACTION; INSERT INTO t1 VALUES (1); --echo # Connection 2 connection con2; --error ER_LOCK_WAIT_TIMEOUT DROP TABLE t1; --echo # Connection default connection default; COMMIT; --echo # --echo # Test 2: upgrade shared lock --echo # --echo # Connection default connection default; START TRANSACTION; SELECT * FROM t1; --echo # Connection 2 connection con2; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t1 RENAME TO t2; --echo # Connection default connection default; COMMIT; --echo # --echo # Test 3: acquire shared lock --echo # --echo # Connection default connection default; LOCK TABLE t1 WRITE; --echo # Connection 2 connection con2; --error ER_LOCK_WAIT_TIMEOUT INSERT INTO t1(id) VALUES (2); --echo # Connection default connection default; UNLOCK TABLES; --echo # --echo # Test 4: table level locks --echo # --echo # Connection default connection default; LOCK TABLE t1 READ; --echo # Connection 2 connection con2; --error ER_LOCK_WAIT_TIMEOUT INSERT INTO t1(id) VALUES(4); --echo # Connection default connection default; UNLOCK TABLES; --echo # --echo # Test 5: Waiting on Table Definition Cache (TDC) --echo # connect(con3, localhost, root); --echo # Connection default connection default; LOCK TABLE t1 READ; --echo # Connection con3 connection con3; --echo # Sending: --send FLUSH TABLES --echo # Connection con2 connection con2; 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 --error ER_LOCK_WAIT_TIMEOUT SELECT * FROM t1; --echo # Connection default connection default; UNLOCK TABLES; --echo # Connection con3 connection con3; --echo # Reaping: FLUSH TABLES --reap --echo # --echo # Test 6: Timeouts in I_S queries --echo # --echo # Connection default connection default; CREATE TABLE t2 (id INT); LOCK TABLE t2 WRITE; --echo # Connection con3 connection con3; --echo # Sending: --send DROP TABLE t1, t2 --echo # Connection con2 connection con2; let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = "Waiting for table metadata lock" AND info = "DROP TABLE t1, t2"; --source include/wait_condition.inc # Note: This query causes two timeouts. # 1: try_acquire_high_prio_shared_mdl_lock on t1 # 2: recover_from_failed_open on t1 SET SESSION information_schema_stats_expiry=0; SELECT table_name, table_rows, table_comment FROM information_schema.tables WHERE table_schema= 'test' AND table_name= 't1'; SET SESSION information_schema_stats_expiry=default; --echo # Connection default connection default; UNLOCK TABLES; --echo # Connection con3 connection con3; --echo # Reaping: DROP TABLE t1, t2 --reap --echo # Connection default connection default; --echo # Cleanup disconnect con2; disconnect con3; --echo # --echo # Test for bug #51134 "Crash in MDL_lock::destroy on a concurrent --echo # DDL workload". --echo # --disable_warnings drop tables if exists t1, t2, t3; --enable_warnings connect (con1, localhost, root, , ); connect (con2, localhost, root, , ); connection default; create table t3 (i int); --echo # Switching to connection 'con1' connection con1; --echo # Lock 't3' so upcoming RENAME is blocked. lock table t3 read; --echo # Switching to connection 'con2' connection con2; --echo # Remember ID for this connection. let $ID= `select connection_id()`; --echo # Start statement which will try to acquire two instances --echo # of X metadata lock on the same object. --echo # Sending: --send rename tables t1 to t2, t2 to t3; --echo # Switching to connection 'default' connection default; --echo # Wait until RENAME TABLE is blocked on table 't3'. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "rename tables t1 to t2, t2 to t3"; --source include/wait_condition.inc --echo # Kill RENAME TABLE. --replace_result $ID ID eval kill query $ID; --echo # Switching to connection 'con2' connection con2; --echo # RENAME TABLE should be aborted but should not crash. --error ER_QUERY_INTERRUPTED --reap --echo # Switching to connection 'con1' connection con1; unlock tables; --echo # Switching to connection 'default' connection default; disconnect con1; disconnect con2; drop table t3; --echo # --echo # Test for the bug where upgradable metadata locks was acquired --echo # even if the table to altered was temporary. --echo # Bug found while working on the related bug #51240. --echo # --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings CREATE TABLE t1 (id INT); LOCK TABLE t1 WRITE; --echo # Connection con1 connect (con1, localhost, root); CREATE TEMPORARY TABLE t1 (id INT); # This alter should not block and timeout. ALTER TABLE t1 ADD COLUMN j INT; --echo # Connection default connection default; disconnect con1; UNLOCK TABLES; DROP TABLE t1; --echo # --echo # Test coverage for LOCK TABLES ... READ/WRITE --echo # --echo # Of course this functionality is well-covered by tests all --echo # around the test suite. Still it is nice to have formal --echo # coverage for LOCK TABLES in one place. --echo # --enable_connect_log --echo # We are going to check behavior for both InnoDB and MyISAM --echo # tables. CREATE TABLE t1 (i INT) ENGINE=MyISAM; CREATE TABLE t2 (i INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); INSERT INTO t2 VALUES (1); CREATE VIEW v1 AS SELECT * FROM t1; CREATE VIEW v2 AS SELECT * FROM t2; CREATE TABLE t3 (j INT); CREATE TABLE t4 (j INT); CREATE VIEW v3 AS SELECT * FROM t3 WHERE (SELECT COUNT(*) FROM t1); CREATE VIEW v4 AS SELECT * FROM t4 WHERE (SELECT COUNT(*) FROM t2); CREATE TABLE t5 (k INT); CREATE TABLE t6 (k INT); CREATE TRIGGER bi_t5 BEFORE INSERT ON t5 FOR EACH ROW SET @a:= (SELECT COUNT(*) FROM t1); CREATE TRIGGER bi_t6 BEFORE INSERT ON t6 FOR EACH ROW SET @a:= (SELECT COUNT(*) FROM t2); CREATE TABLE t7 (z INT); CREATE TABLE t8 (z INT); CREATE TRIGGER bi_t7 BEFORE INSERT ON t7 FOR EACH ROW INSERT INTO t1 VALUES (1); CREATE TRIGGER bi_t8 BEFORE INSERT ON t8 FOR EACH ROW INSERT INTO t2 VALUES (1); --echo # --echo # 1) LOCK TABLES READ explicitly locking table --echo # --echo # 1.a) Allows concurrent reads LOCK TABLE t1 READ, t2 READ; connect (con1, localhost, root); SELECT * FROM t1; SELECT * FROM t2; connection default; UNLOCK TABLES; --echo # --echo # 1.b) Is allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2; connect (con2, localhost, root); --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2"; --source include/wait_condition.inc --echo # LOCK TABLES should not be blocked. LOCK TABLES t1 READ, t2 READ; UNLOCK TABLES; connection default; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); --echo # --echo # 1.c) Blocks concurrent modifications to table connection default; LOCK TABLE t1 READ, t2 READ; connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (1) connection default; --echo # Wait until INSERT gets 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 connection con2; --echo # Sending: --send INSERT INTO t2 VALUES (1) connection default; --echo # Wait until INSERT gets 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 INSERTs UNLOCK TABLES; connection con1; --echo # Reap INSERT --reap connection con2; --echo # Reap INSERT --reap connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 1.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t1 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t1 READ"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES READ --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); --echo # --echo # The below part of test also covers scenario in which bug #42147 --echo # "Concurrent DML and LOCK TABLE ... READ for InnoDB table cause --echo # warnings in errlog" occurred. --echo # connection con1; --echo # Sending: --send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t2 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t2 READ"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES READ --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 1.e) LOCK TABLES READ which explicitly locks table is not blocked --echo # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; connection con1; LOCK TABLES t1 READ; UNLOCK TABLES; connection default; COMMIT; BEGIN; SELECT * FROM t2; connection con1; LOCK TABLES t2 READ; UNLOCK TABLES; connection default; COMMIT; --echo # --echo # 1.f) LOCK TABLES READ which explicitly locks table is blocked --echo # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES t1 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t1 READ"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES READ COMMIT; connection con1; --echo # Reap LOCK TABLES READ --reap UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES t2 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t2 READ"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES READ COMMIT; connection con1; --echo # Reap LOCK TABLES READ --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 1.g) LOCK TABLES READ which explicitly locks table is compatible --echo # with itself. LOCK TABLES t1 READ, t2 READ; connection con1; LOCK TABLES t1 READ, t2 READ; UNLOCK TABLES; connection default; UNLOCK TABLES; --echo # --echo # 1.h) LOCK TABLES READ which explicitly locks table is not compatible --echo # with LOCK TABLE WRITE. LOCK TABLES t1 READ; connection con1; --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait 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 # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES t2 READ; connection con1; --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait 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 t2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES t1 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t1 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t1 READ"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES READ UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES READ --reap UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t2 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t2 READ"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES READ UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES READ --reap UNLOCK TABLES; --echo # --echo # 2) LOCK TABLES WRITE explicitly locking table --echo # --echo # 2.a) Doesn't allow concurrent reads connection default; LOCK TABLE t1 WRITE; connection con1; --echo # Sending: --send SELECT * FROM t1; connection default; --echo # Wait until SELECT gets blocked 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 # Unblock SELECT UNLOCK TABLES; connection con1; --echo # Reaping SELECT --reap connection default; LOCK TABLE t2 WRITE; connection con1; --echo # Sending: --send SELECT * FROM t2; connection default; --echo # Wait until SELECT gets blocked 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 # Unblock SELECT UNLOCK TABLES; connection con1; --echo # Reaping SELECT --reap connection default; --echo # --echo # 2.b) Is not allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1; connection con2; --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; 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 UNLOCK TABLES; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLE WRITE --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t2; connection con2; --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t2"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t2 WRITE"; --source include/wait_condition.inc UNLOCK TABLES; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLE WRITE --reap UNLOCK TABLES; --echo # --echo # 2.c) Blocks concurrent modifications to table connection default; LOCK TABLE t1 WRITE, t2 WRITE; connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (1) connection default; --echo # Wait until INSERT gets 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 connection con2; --echo # Sending: --send INSERT INTO t2 VALUES (1) connection default; --echo # Wait until INSERT gets 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 INSERTs UNLOCK TABLES; connection con1; --echo # Reap INSERT --reap connection con2; --echo # Reap INSERT --reap connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 2.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due to INSERT 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 # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t2 WRITE"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 2.e) LOCK TABLES WRITE which explicitly locks table is blocked --echo # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; connection con1; --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction 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 # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; BEGIN; SELECT * FROM t2; connection con1; --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; --echo # --echo # 2.f) LOCK TABLES WRITE which explicitly locks table is blocked --echo # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction 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 # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 2.g) LOCK TABLES WRITE which explicitly locks table is not compatible --echo # with itself. LOCK TABLES t1 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait 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 # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait 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 t2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; --echo # --echo # 3) LOCK TABLES which locks table for read through view. --echo # Case of main table in mergeable view. --echo # --echo # 3.a) Allows concurrent reads connection default; LOCK TABLE v1 READ, v2 READ; connection con1; SELECT * FROM t1; SELECT * FROM t2; connection default; UNLOCK TABLES; --echo # --echo # 3.b) Is allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2; connection con2; --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2"; --source include/wait_condition.inc --echo # LOCK TABLES should not be blocked. LOCK TABLES v1 READ, v2 READ; UNLOCK TABLES; connection default; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); --echo # --echo # 3.c) Blocks concurrent modifications to table connection default; LOCK TABLE v1 READ, v2 READ; connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (1) connection default; --echo # Wait until INSERT gets 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 connection con2; --echo # Sending: --send INSERT INTO t2 VALUES (1) connection default; --echo # Wait until INSERT gets 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 INSERTs UNLOCK TABLES; connection con1; --echo # Reap INSERT --reap connection con2; --echo # Reap INSERT --reap connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 3.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES v1 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v1 READ"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES READ --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES v2 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v2 READ"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES READ --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 3.e) LOCK TABLES which locks table for read through view is not blocked --echo # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; connection con1; LOCK TABLES v1 READ; UNLOCK TABLES; connection default; COMMIT; BEGIN; SELECT * FROM t2; connection con1; LOCK TABLES v2 READ; UNLOCK TABLES; connection default; COMMIT; --echo # --echo # 3.f) LOCK TABLES which locks table for read through view is blocked --echo # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES v1 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v1 READ"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES READ COMMIT; connection con1; --echo # Reap LOCK TABLES READ --reap UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES v2 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v2 READ"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES READ COMMIT; connection con1; --echo # Reap LOCK TABLES READ --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 3.g) LOCK TABLES READ which locks table for read through view is --echo # compatible with explicit LOCK TABLES READ on the same table. LOCK TABLES t1 READ, t2 READ; connection con1; LOCK TABLES v1 READ, v2 READ; UNLOCK TABLES; connection default; UNLOCK TABLES; --echo # --echo # 3.h) LOCK TABLES READ which locks table for read through view is --echo # not compatible with explicit LOCK TABLES WRITE on the same table. LOCK TABLES v1 READ; connection con1; --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait 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 # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES v2 READ; connection con1; --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait 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 t2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES t1 WRITE; connection con1; --echo # Sending: --send LOCK TABLES v1 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v1 READ"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES READ UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES READ --reap UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; --echo # Sending: --send LOCK TABLES v2 READ; connection default; --echo # Wait until LOCK TABLES READ is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v2 READ"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES READ UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES READ --reap UNLOCK TABLES; --echo # --echo # 4) LOCK TABLES which locks table for read through mergeable view. --echo # Case of table not from the main join. Such table will be locked --echo # for read even though view is locked for write. --echo # 4.a) Allows concurrent reads connection default; LOCK TABLES v3 WRITE, v4 WRITE; connection con1; SELECT * FROM t1; SELECT * FROM t2; connection default; UNLOCK TABLES; --echo # --echo # 4.b) Is allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2; connection con2; --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2"; --source include/wait_condition.inc --echo # LOCK TABLES should not be blocked. LOCK TABLES v3 WRITE, v4 WRITE; UNLOCK TABLES; connection default; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); --echo # --echo # 4.c) Blocks concurrent modifications to table connection default; LOCK TABLES v3 WRITE, v4 WRITE; connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (1) connection default; --echo # Wait until INSERT gets 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 connection con2; --echo # Sending: --send INSERT INTO t2 VALUES (1) connection default; --echo # Wait until INSERT gets 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 INSERTs UNLOCK TABLES; connection con1; --echo # Reap INSERT --reap connection con2; --echo # Reap INSERT --reap connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 4.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES v3 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v3 WRITE"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES v4 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v4 WRITE"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 4.e) LOCK TABLES which locks table for read through view is not blocked --echo # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; connection con1; LOCK TABLES v3 WRITE; UNLOCK TABLES; connection default; COMMIT; BEGIN; SELECT * FROM t2; connection con1; LOCK TABLES v4 WRITE; UNLOCK TABLES; connection default; COMMIT; --echo # --echo # 4.f) LOCK TABLES which locks table for read through view is blocked --echo # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES v3 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v3 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES COMMIT; connection con1; --echo # Reap LOCK TABLES --reap UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES v4 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v4 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES COMMIT; connection con1; --echo # Reap LOCK TABLES --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 4.g) LOCK TABLES which locks table for read through view is --echo # compatible with explicit LOCK TABLES READ on the same table. LOCK TABLES t1 READ, t2 READ; connection con1; LOCK TABLES v3 WRITE, v4 WRITE; UNLOCK TABLES; connection default; UNLOCK TABLES; --echo # --echo # 4.h) LOCK TABLES which locks table for read through view is --echo # not compatible with explicit LOCK TABLES WRITE on the same table. LOCK TABLES v3 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait 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 # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES v4 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait 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 t2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES t1 WRITE; connection con1; --echo # Sending: --send LOCK TABLES v3 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v3 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES --reap UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; --echo # Sending: --send LOCK TABLES v4 WRITE; connection default; --echo # Wait 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 v4 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES --reap UNLOCK TABLES; --echo # --echo # 5) LOCK TABLES which locks tables for write through view --echo # --echo # 5.a) Doesn't allow concurrent reads connection default; LOCK TABLE v1 WRITE; connection con1; --echo # Sending: --send SELECT * FROM t1; connection default; --echo # Wait until SELECT gets blocked 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 # Unblock SELECT UNLOCK TABLES; connection con1; --echo # Reaping SELECT --reap connection default; LOCK TABLE v2 WRITE; connection con1; --echo # Sending: --send SELECT * FROM t2; connection default; --echo # Wait until SELECT gets blocked 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 # Unblock SELECT UNLOCK TABLES; connection con1; --echo # Reaping SELECT --reap connection default; --echo # --echo # 5.b) Is not allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1; connection con2; --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES v1 WRITE; connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v1 WRITE"; --source include/wait_condition.inc UNLOCK TABLES; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLE WRITE --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t2; connection con2; --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t2"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES v2 WRITE; connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v2 WRITE"; --source include/wait_condition.inc UNLOCK TABLES; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLE WRITE --reap UNLOCK TABLES; --echo # --echo # 5.c) Blocks concurrent modifications to table connection default; LOCK TABLE v1 WRITE, v2 WRITE; connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (1) connection default; --echo # Wait until INSERT gets 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 connection con2; --echo # Sending: --send INSERT INTO t2 VALUES (1) connection default; --echo # Wait until INSERT gets 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 INSERTs UNLOCK TABLES; connection con1; --echo # Reap INSERT --reap connection con2; --echo # Reap INSERT --reap connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 5.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES v1 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v1 WRITE"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES v2 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v2 WRITE"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 5.e) LOCK TABLES which locks table for write through view is blocked --echo # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; connection con1; --echo # Sending: --send LOCK TABLES v1 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v1 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; BEGIN; SELECT * FROM t2; connection con1; --echo # Sending: --send LOCK TABLES v2 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; --echo # --echo # 5.f) LOCK TABLES which locks table for write through view is blocked --echo # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES v1 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v1 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES v2 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES v2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 5.g) LOCK TABLES which locks table for write through view is not --echo # compatible with LOCK TABLE WRITE. LOCK TABLES v1 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait 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 # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES v2 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait 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 t2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; --echo # --echo # 6) LOCK TABLES which locks table for read through trigger. --echo # --echo # 6.a) Allows concurrent reads connection default; LOCK TABLES t5 WRITE, t6 WRITE; connection con1; SELECT * FROM t1; SELECT * FROM t2; connection default; UNLOCK TABLES; --echo # --echo # 6.b) Is allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2; connection con2; --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2"; --source include/wait_condition.inc --echo # LOCK TABLES should not be blocked. LOCK TABLES v3 WRITE, t6 WRITE; UNLOCK TABLES; connection default; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); --echo # --echo # 6.c) Blocks concurrent modifications to table connection default; LOCK TABLES t5 WRITE, t6 WRITE; connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (1) connection default; --echo # Wait until INSERT gets 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 connection con2; --echo # Sending: --send INSERT INTO t2 VALUES (1) connection default; --echo # Wait until INSERT gets 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 INSERTs UNLOCK TABLES; connection con1; --echo # Reap INSERT --reap connection con2; --echo # Reap INSERT --reap connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 6.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t5 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t5 WRITE"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t6 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t6 WRITE"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 6.e) LOCK TABLES which locks table for read through trigger is not --echo # blocked by concurrent transactions which read table. BEGIN; SELECT * FROM t1; connection con1; LOCK TABLES t5 WRITE; UNLOCK TABLES; connection default; COMMIT; BEGIN; SELECT * FROM t2; connection con1; LOCK TABLES t6 WRITE; UNLOCK TABLES; connection default; COMMIT; --echo # --echo # 6.f) LOCK TABLES which locks table for read through trigger is --echo # blocked by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES t5 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t5 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES COMMIT; connection con1; --echo # Reap LOCK TABLES --reap UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES t6 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t6 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES COMMIT; connection con1; --echo # Reap LOCK TABLES --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 6.g) LOCK TABLES which locks table for read through trigger is --echo # compatible with explicit LOCK TABLES READ on the same table. LOCK TABLES t1 READ, t2 READ; connection con1; LOCK TABLES t5 WRITE, t6 WRITE; UNLOCK TABLES; connection default; UNLOCK TABLES; --echo # --echo # 6.h) LOCK TABLES which locks table for read through trigger is --echo # not compatible with explicit LOCK TABLES WRITE on the same table. LOCK TABLES t5 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait 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 # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES t6 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait 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 t2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES t1 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t5 WRITE; connection default; --echo # Wait until LOCK TABLES is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t5 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES --reap UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t6 WRITE; connection default; --echo # Wait 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 t6 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES --reap UNLOCK TABLES; --echo # --echo # 7) LOCK TABLES which locks tables for write through trigger --echo # --echo # 7.a) Doesn't allow concurrent reads connection default; LOCK TABLE t7 WRITE; connection con1; --echo # Sending: --send SELECT * FROM t1; connection default; --echo # Wait until SELECT gets blocked 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 # Unblock SELECT UNLOCK TABLES; connection con1; --echo # Reaping SELECT --reap connection default; LOCK TABLE t8 WRITE; connection con1; --echo # Sending: --send SELECT * FROM t2; connection default; --echo # Wait until SELECT gets blocked 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 # Unblock SELECT UNLOCK TABLES; connection con1; --echo # Reaping SELECT --reap connection default; --echo # --echo # 7.b) Is not allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t1; connection con2; --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t1"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t7 WRITE; connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t7 WRITE"; --source include/wait_condition.inc UNLOCK TABLES; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLE WRITE --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Start read by sending SELECT: --send SELECT GET_LOCK('mysqltest_lock', 100) FROM t2; connection con2; --echo # Wait until SELECT gets read lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "SELECT GET_LOCK('mysqltest_lock', 100) FROM t2"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t8 WRITE; connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t8 WRITE"; --source include/wait_condition.inc UNLOCK TABLES; --echo # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping SELECT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLE WRITE --reap UNLOCK TABLES; --echo # --echo # 7.c) Blocks concurrent modifications to table connection default; LOCK TABLE t7 WRITE, t8 WRITE; connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (1) connection default; --echo # Wait until INSERT gets 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 connection con2; --echo # Sending: --send INSERT INTO t2 VALUES (1) connection default; --echo # Wait until INSERT gets 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 INSERTs UNLOCK TABLES; connection con1; --echo # Reap INSERT --reap connection con2; --echo # Reap INSERT --reap connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 7.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t7 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t7 WRITE"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); connection con1; --echo # Sending: --send INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100)); connection con2; --echo # Wait until INSERT gets SW MDL lock and starts waiting for user lock let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "User lock" and info = "INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100))"; --source include/wait_condition.inc --echo # Sending: --send LOCK TABLES t8 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due to INSERT let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t8 WRITE"; --source include/wait_condition.inc --echo # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); connection con1; --echo # Reaping INSERT --reap SELECT RELEASE_LOCK('mysqltest_lock'); connection con2; --echo # Reaping LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 7.e) LOCK TABLES which locks table for write through trigger is blocked --echo # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; connection con1; --echo # Sending: --send LOCK TABLES t7 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t7 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; BEGIN; SELECT * FROM t2; connection con1; --echo # Sending: --send LOCK TABLES t8 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t8 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; --echo # --echo # 7.f) LOCK TABLES which locks table for write through trigger is blocked --echo # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES t7 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t7 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; --echo # Sending: --send LOCK TABLES t8 WRITE; connection default; --echo # Wait until LOCK TABLES WRITE is blocked due concurrent transaction let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOCK TABLES t8 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE COMMIT; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; --echo # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; --echo # --echo # 7.g) LOCK TABLES which locks table for write through trigger is not --echo # compatible with LOCK TABLE WRITE. LOCK TABLES t7 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t1 WRITE; connection default; --echo # Wait 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 # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; connection default; LOCK TABLES t8 WRITE; connection con1; --echo # Sending: --send LOCK TABLES t2 WRITE; connection default; --echo # Wait 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 t2 WRITE"; --source include/wait_condition.inc --echo # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; --echo # Reap LOCK TABLES WRITE --reap UNLOCK TABLES; disconnect con1; disconnect con2; connection default; DROP VIEW v1, v2, v3, v4; DROP TABLES t1, t2, t3, t4, t5, t6, t7, t8; --disable_connect_log --echo # --echo # Test coverage for LOCK TABLES ... READ LOCAL --echo # --enable_connect_log SET @old_concurrent_insert= @@global.concurrent_insert; SET @@global.concurrent_insert= 1; CREATE TABLE t1 (i INT) ENGINE=MyISAM; CREATE TABLE t2 (i INT) ENGINE=InnoDB; CREATE VIEW v1 AS SELECT * FROM t1; CREATE VIEW v2 AS (SELECT * FROM t1) UNION (SELECT * FROM t1); CREATE VIEW v3 AS SELECT * FROM t2; --echo # --echo # 1) READ LOCAL is fully supported for MyISAM. --echo # Concurrent inserts are allowed. --echo # LOCK TABLE t1 READ LOCAL; connect (con1, localhost, root); INSERT INTO t1 VALUES (1); --echo # --echo # Concurrent updates are blocked. --echo # --echo # Sending: --send UPDATE t1 SET i= 2 connection default; --echo # Wait until UPDATE is blocked. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and info = "UPDATE t1 SET i= 2"; --source include/wait_condition.inc UNLOCK TABLES; connection con1; --echo # Reaping UPDATE. --reap --echo # --echo # 2) READ LOCAL works even for mergeable views on --echo # top of MyISAM tables. --echo # connection default; LOCK TABLE v1 READ LOCAL; connection con1; INSERT INTO v1 VALUES (1); INSERT INTO t1 VALUES (3); --echo # Concurrent updates are blocked. --echo # Sending: --send UPDATE t1 SET i= 2 connection default; --echo # Wait until UPDATE is blocked. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and info = "UPDATE t1 SET i= 2"; --source include/wait_condition.inc UNLOCK TABLES; connection con1; --echo # Reaping UPDATE. --reap --echo # --echo # 3) READ LOCAL doesn't work for non-mergeable views on --echo # top of MyISAM tables. --echo # connection default; LOCK TABLE v2 READ LOCAL; connection con1; --echo # Sending: --send INSERT INTO t1 VALUES (1) connection default; --echo # Wait until 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 UNLOCK TABLES; connection con1; --echo # Reaping INSERT. --reap connection default; LOCK TABLE v2 READ LOCAL; connection con1; --echo # Sending: --send UPDATE t1 SET i= 2; connection default; --echo # Wait until UPDATE is blocked. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "UPDATE t1 SET i= 2"; --source include/wait_condition.inc UNLOCK TABLES; connection con1; --echo # Reaping UPDATE. --reap --echo # --echo # 4) READ LOCAL locks are upgraded to simple READ locks --echo # for InnoDB tables. So they block both concurrent inserts --echo # and updates. --echo # connection default; LOCK TABLE t2 READ LOCAL; connection con1; --echo # Sending: --send INSERT INTO t2 VALUES (1) connection default; --echo # Wait until 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 UNLOCK TABLES; connection con1; --echo # Reaping INSERT. --reap connection default; LOCK TABLE t2 READ LOCAL; connection con1; --echo # Sending: --send UPDATE t2 SET i= 2; connection default; --echo # Wait until UPDATE is blocked. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "UPDATE t2 SET i= 2"; --source include/wait_condition.inc UNLOCK TABLES; connection con1; --echo # Reaping UPDATE. --reap --echo # --echo # 5) For mergeable views on top of InnoDB tables READ LOCAL locks are --echo # upgraded to simple READ locks as well. --echo # connection default; LOCK TABLE v3 READ LOCAL; connection con1; --echo # Sending: --send INSERT INTO t2 VALUES (1) connection default; --echo # Wait until 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 UNLOCK TABLES; connection con1; --echo # Reaping INSERT. --reap connection default; LOCK TABLE v3 READ LOCAL; connection con1; --echo # Sending: --send UPDATE t2 SET i= 2; connection default; --echo # Wait until UPDATE is blocked. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "UPDATE t2 SET i= 2"; --source include/wait_condition.inc UNLOCK TABLES; connection con1; --echo # Reaping UPDATE. --reap connection default; disconnect con1; DROP VIEW v1, v2, v3; DROP TABLES t1, t2; SET @@global.concurrent_insert= @old_concurrent_insert; --disable_connect_log --echo # --echo # Test coverage for interaction between LOCK TABLE ... READ and --echo # concurrent DML which uses LOW_PRIORITY and HIGH_PRIORITY clauses/ --echo # concurrent DML which is executed in @@low_priority_updates=1 mode. --echo # --enable_connect_log --echo # We will use MyISAM to avoid row-locks. CREATE TABLE t1 (i INT) ENGINE=MyISAM; CREATE VIEW v1 AS SELECT * FROM t1; CREATE TABLE t2 (j INT); CREATE TRIGGER t2_ai AFTER INSERT ON t2 FOR EACH ROW INSERT LOW_PRIORITY INTO t1 VALUES (2); CREATE TABLE t3 (k INT); CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t1 VALUES (2); CREATE TABLE tm (i INT) ENGINE=MERGE UNION=(t1); --echo # --echo # 1) Let us check that DML operations with LOW_PRIORITY clauses have --echo # lower priority than pending LOCK TABLE ... READ, thus can't starve --echo # it out. --echo # --echo # Acquire SW lock on the table, to create pending LOCK TABLE ... READ. BEGIN; INSERT INTO t1 VALUES (1); connect (blocker, localhost, root); --echo # Sending: --send LOCK TABLE t1 READ; connection default; --echo # Wait until LOCK TABLE READ gets blocked 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 connect (con_insert, localhost, root); --echo # INSERT HIGH_PRIORITY should not get blocked INSERT HIGH_PRIORITY INTO t1 VALUES (1); --echo # Sending: --send INSERT LOW_PRIORITY INTO t1 VALUES (1); connection default; --echo # Check that INSERT is blocked 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 connect (con_replace, localhost, root); --echo # Sending: --send REPLACE LOW_PRIORITY INTO t1 VALUES (1); connection default; --echo # Check that REPLACE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "REPLACE LOW_PRIORITY INTO t1 VALUES (1)"; --source include/wait_condition.inc connect (con_update, localhost, root); --echo # Sending: --send UPDATE LOW_PRIORITY t1 SET i= 1; connection default; --echo # Check that UPDATE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "UPDATE LOW_PRIORITY t1 SET i= 1"; --source include/wait_condition.inc connect (con_update_multi, localhost, root); --echo # Sending: --send UPDATE LOW_PRIORITY t1 AS a, t1 AS b SET a.i= 1; connection default; --echo # Check that multi-UPDATE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "UPDATE LOW_PRIORITY t1 AS a, t1 AS b SET a.i= 1"; --source include/wait_condition.inc connect (con_delete, localhost, root); --echo # Sending: --send DELETE LOW_PRIORITY FROM t1 LIMIT 1; connection default; --echo # Check that DELETE is blocked 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 connect (con_delete_multi, localhost, root); --echo # Sending: --send DELETE LOW_PRIORITY FROM a USING t1 AS a, t1 AS b; connection default; --echo # Check that multi-DELETE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "DELETE LOW_PRIORITY FROM a USING t1 AS a, t1 AS b"; --source include/wait_condition.inc connect (con_load, localhost, root); --echo # Sending: --send LOAD DATA LOW_PRIORITY INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i); connection default; --echo # Check that LOAD DATA is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOAD DATA LOW_PRIORITY INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i)"; --source include/wait_condition.inc --echo # --echo # This should work even for views. --echo # connect (con_view, localhost, root); --echo # Sending: --send DELETE LOW_PRIORITY FROM v1; connection default; --echo # Check that DELETE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "DELETE LOW_PRIORITY FROM v1"; --source include/wait_condition.inc --echo # --echo # And when LOW_PRIORITY clause is used in trigger. --echo # connect (con_trigger, localhost, root); --echo # Sending: --send INSERT INTO t2 VALUES (1); connection default; --echo # Check that INSERT in trigger 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 # --echo # And for MERGE tables --echo # connect (con_merge, localhost, root); --echo # Sending: --send DELETE LOW_PRIORITY FROM tm LIMIT 1; connection default; --echo # Check that DELETE from MERGE table is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "DELETE LOW_PRIORITY FROM tm LIMIT 1"; --source include/wait_condition.inc --echo # Unblock LOCK TABLE .. READ COMMIT; connection blocker; --echo # Reaping LOCK TABLE .. READ --reap UNLOCK TABLES; --echo # Reap all DML statements. connection con_insert; --reap connection con_replace; --reap connection con_update; --reap connection con_update_multi; --reap connection con_delete; --reap connection con_delete_multi; --reap connection con_load; --reap connection con_view; --reap connection con_trigger; --reap connection con_merge; --reap connection default; --echo # --echo # 2) Let us check that DML operations have lower priority than pending --echo # LOCK TABLE ... READ when @@low_priority_updates mode is on. --echo # --echo # Acquire SW lock on the table, to create pending LOCK TABLE ... READ. BEGIN; INSERT INTO t1 VALUES (0); connection blocker; --echo # Sending: --send LOCK TABLE t1 READ; connection default; --echo # Wait until LOCK TABLE READ gets blocked 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 connection con_insert; SET @@session.low_priority_updates= 1; --echo # INSERT HIGH_PRIORITY still should not get blocked INSERT HIGH_PRIORITY INTO t1 VALUES (1); --echo # Sending: --send INSERT INTO t1 VALUES (1); connection default; --echo # Check that 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 connection con_replace; SET @@session.low_priority_updates= 1; --echo # Sending: --send REPLACE INTO t1 VALUES (1); connection default; --echo # Check that REPLACE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "REPLACE INTO t1 VALUES (1)"; --source include/wait_condition.inc connection con_update; SET @@session.low_priority_updates= 1; --echo # Sending: --send UPDATE t1 SET i= 1; connection default; --echo # Check that UPDATE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "UPDATE t1 SET i= 1"; --source include/wait_condition.inc connection con_update_multi; SET @@session.low_priority_updates= 1; --echo # Sending: --send UPDATE t1 AS a, t1 AS b SET a.i= 1; connection default; --echo # Check that multi-UPDATE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "UPDATE t1 AS a, t1 AS b SET a.i= 1"; --source include/wait_condition.inc connection con_delete; SET @@session.low_priority_updates= 1; --echo # Sending: --send DELETE FROM t1 LIMIT 1; connection default; --echo # Check that DELETE is blocked 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 connection con_delete_multi; SET @@session.low_priority_updates= 1; --echo # Sending: --send DELETE FROM a USING t1 AS a, t1 AS b; connection default; --echo # Check that multi-DELETE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "DELETE FROM a USING t1 AS a, t1 AS b"; --source include/wait_condition.inc connection con_load; SET @@session.low_priority_updates= 1; --echo # Sending: --send LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i); connection default; --echo # Check that LOAD DATA is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i)"; --source include/wait_condition.inc connection con_view; SET @@session.low_priority_updates= 1; --echo # Sending: --send DELETE FROM v1; connection default; --echo # Check that DELETE is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "DELETE FROM v1"; --source include/wait_condition.inc --echo # --echo # And when table used in trigger. --echo # connection con_trigger; SET @@session.low_priority_updates= 1; --echo # Sending: --send INSERT INTO t3 VALUES (1); connection default; --echo # Check that INSERT in trigger is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "INSERT INTO t3 VALUES (1)"; --source include/wait_condition.inc --echo # --echo # And for MERGE tables --echo # connection con_merge; SET @@session.low_priority_updates= 1; --echo # Sending: --send DELETE FROM tm LIMIT 1; connection default; --echo # Check that DELETE from MERGE table is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "DELETE FROM tm LIMIT 1"; --source include/wait_condition.inc --echo # Unblock LOCK TABLE .. READ COMMIT; connection blocker; --echo # Reaping LOCK TABLE .. READ --reap UNLOCK TABLES; --echo # Reap all DML statements. connection con_insert; --reap connection con_replace; --reap connection con_update; --reap connection con_update_multi; --reap connection con_delete; --reap connection con_delete_multi; --reap connection con_load; --reap connection con_view; --reap connection con_trigger; --reap connection con_merge; --reap connection default; disconnect blocker; disconnect con_insert; disconnect con_replace; disconnect con_update; disconnect con_update_multi; disconnect con_delete; disconnect con_delete_multi; disconnect con_load; disconnect con_view; disconnect con_trigger; disconnect con_merge; DROP VIEW v1; DROP TABLES tm, t2, t3, t1; --disable_connect_log --echo # --echo # Test for bug #11764618 "DEADLOCK WHEN DDL UNDER LOCK TABLES --echo # WRITE, READ + PREPARE". --echo # --enable_connect_log connect (con1,localhost,root,,test,,); connect (con2,localhost,root,,test,,); connect (con3,localhost,root,,test,,); connection default; create table t1(i int); create table t2(i int); create table t3(i int); create table t4(i int); lock tables t1 write, t3 read; connection con1; begin; select count(*) from t4; --echo # Sending: --send insert into t3 values (1); connection con2; --echo # Wait until 'con1' acquires SR metadata lock on 't4' --echo # and blocks on 't3'. Before WL#6671 waiting has happened --echo # on THR_LOCK lock which led to deadlock. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "insert into t3 values (1)"; --source include/wait_condition.inc --echo # Sending: --send rename table t2 to t0, t4 to t2, t0 to t4; connection con3; --echo # Wait until RENAME acquires X metadata lock on 't2' --echo # and blocks on 't4'. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "rename table t2 to t0, t4 to t2, t0 to t4"; --source include/wait_condition.inc --echo # Sending: --send prepare stmt1 from 'select * from t1, t2'; connection default; --echo # Wait until PREPARE acquires S metadata lock on 't1' --echo # and blocks on 't2'. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "PREPARE stmt1 FROM ..."; --source include/wait_condition.inc --echo # This ALTER TABLE upgrades SNRW lock on t1 to X lock. --echo # In the past this caused deadlock. alter table t1 add column j int; unlock tables; connection con1; --echo # Reap INSERT --reap commit; connection con2; --echo # Reap RENAME --reap connection con3; --echo # Reap PREPARE --reap connection default; disconnect con1; disconnect con2; disconnect con3; drop tables t1, t2, t3, t4; --disable_connect_log # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc