Current Path : /usr/opt/mysql57/mysql-test/r/ |
FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64 |
Current File : //usr/opt/mysql57/mysql-test/r/lock_multi.result |
drop table if exists t1,t2; create table t1(n int); insert into t1 values (1); select get_lock("mysqltest_lock", 100); get_lock("mysqltest_lock", 100) 1 update t1 set n = 2 and get_lock('mysqltest_lock', 100); update low_priority t1 set n = 4; select n from t1; select release_lock("mysqltest_lock"); release_lock("mysqltest_lock") 1 select release_lock("mysqltest_lock"); release_lock("mysqltest_lock") 1 n 4 drop table t1; create table t1(n int); insert into t1 values (1); select get_lock("mysqltest_lock", 100); get_lock("mysqltest_lock", 100) 1 select n from t1 where get_lock('mysqltest_lock', 100); update low_priority t1 set n = 4; select n from t1; n 1 select release_lock("mysqltest_lock"); release_lock("mysqltest_lock") 1 n 1 select release_lock("mysqltest_lock"); release_lock("mysqltest_lock") 1 drop table t1; # # Test locking in multi-update statements. # # # Multi-update should not be blocked by THR_LOCK locks acquired # on table which is not updated. # 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); get_lock("mysqltest_lock", 100) 1 connection locker; # Sending: select a from t1 where get_lock('mysqltest_lock', 100); connection writer; # Wait till above select gets blocked on a user lock. update t1,t2 set c=a where b=d; connection reader; select c from t2; c 2 connection locker2; select release_lock("mysqltest_lock"); release_lock("mysqltest_lock") 1 connection locker; # Reap select. a 1 2 select release_lock("mysqltest_lock"); release_lock("mysqltest_lock") 1 # # Indeed it should be blocked by THR_LOCK locks on table # which is updated. # connection locker2; select get_lock("mysqltest_lock", 100); get_lock("mysqltest_lock", 100) 1 connection locker; # Sending: select c from t2 where get_lock('mysqltest_lock', 100); connection writer; # Wait till above select gets blocked on a user lock. # Sending: update t1,t2 set c=a where b=d;; connection default; # Wait till multi-update is blocked on THR_LOCK lock connection locker2; select release_lock("mysqltest_lock"); release_lock("mysqltest_lock") 1 connection locker; # Reap select. c 2 select release_lock("mysqltest_lock"); release_lock("mysqltest_lock") 1 connection writer; # Reap multi-update. # # OTOH multi-update will be blocked by concurrent LOCK TABLES READ # on any table in the join. This is because multi-update acquires # SW metadata locks on all tables in the join which conflicts with # SRO metadata lock acquired by LOCK TABLES READ. # connection locker; lock table t1 read; connection writer; # Sending: update t1,t2 set c=a where b=d;; connection default; # Wait till multi-update is blocked on THR_LOCK lock connection locker; unlock tables; connection writer; # Reap multi-update. connection locker; lock table t2 read; connection writer; # Sending: update t1,t2 set c=a where b=d;; connection default; # Wait till multi-update is blocked on THR_LOCK lock connection locker; unlock tables; connection writer; # Reap multi-update. # # Still if multi-update is executed under LOCK TABLES # it will be compatible with LOCK TABLES READ on the # table from its join which is only read. # # Main difference here is that LOCK TABLES preannounces # locks which will be requested by multi-update. # 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; create table t1 (a int); create table t2 (a int); lock table t1 write, t2 write; insert t1 select * from t2; drop table t2; unlock tables; ERROR 42S02: Table 'test.t2' doesn't exist drop table t1; 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; insert t1 select * from t2; drop table t2; unlock tables; ERROR 42S02: Table 'test.t2' doesn't exist drop table t1; End of 4.1 tests create table t1(a int); lock tables t1 write; show columns from t1; Field Type Null Key Default Extra a int(11) YES NULL unlock tables; drop table t1; USE mysql; LOCK TABLES columns_priv WRITE, db WRITE, user WRITE; FLUSH TABLES; USE mysql; SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1; OPTIMIZE TABLES columns_priv, db, user; Table Op Msg_type Msg_text mysql.columns_priv optimize status OK mysql.db optimize status OK mysql.user optimize status OK UNLOCK TABLES; Select_priv N USE test; use test; CREATE TABLE t1 (c1 int); LOCK TABLE t1 WRITE; FLUSH TABLES WITH READ LOCK; CREATE TABLE t2 (c1 int); ERROR HY000: Table 't2' was not locked with LOCK TABLES UNLOCK TABLES; UNLOCK TABLES; DROP TABLE t1; CREATE TABLE t1 (c1 int); LOCK TABLE t1 WRITE; FLUSH TABLES WITH READ LOCK; CREATE TABLE t2 AS SELECT * FROM t1; ERROR HY000: Table 't2' was not locked with LOCK TABLES UNLOCK TABLES; UNLOCK TABLES; DROP TABLE t1; CREATE DATABASE mysqltest_1; FLUSH TABLES WITH READ LOCK; DROP DATABASE mysqltest_1; DROP DATABASE mysqltest_1; ERROR HY000: Can't execute the query because you have a conflicting read lock UNLOCK TABLES; DROP DATABASE mysqltest_1; ERROR HY000: Can't drop database 'mysqltest_1'; database doesn't exist create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb; lock tables t1 write; alter table t1 auto_increment=0; alter table t1 auto_increment=0; unlock tables; drop table t1; create table t1 (a int); create table t2 like t1; # con1 lock tables t1 write; # con2 flush tables with read lock; # con5 # global read lock is taken # con3 select * from t2 for update; # waiting for release of read lock # con4 # would hang and later cause a deadlock flush tables t2; # clean up unlock tables; unlock tables; a drop table t1,t2; # # Lightweight version: # Ensure that the wait for a GRL is done before opening tables. # create table t1 (a int); create table t2 like t1; # # UPDATE # # default flush tables with read lock; # con1 update t2 set a = 1; # default # statement is waiting for release of read lock # con2 flush table t2; # default unlock tables; # con1 # # LOCK TABLES .. WRITE # # default flush tables with read lock; # con1 lock tables t2 write; # default # statement is waiting for release of read lock # con2 flush table t2; # default unlock tables; # con1 unlock tables; drop table t1,t2; End of 5.0 tests create table t1 (i int); insert into t1 values (1); select get_lock('mysqltest_lock', 100); get_lock('mysqltest_lock', 100) 1 select * from t1 where get_lock('mysqltest_lock', 100); update t1 set i= 10; select * from t1; kill query ID; i 1 ERROR 70100: Query execution was interrupted select release_lock('mysqltest_lock'); release_lock('mysqltest_lock') 1 i 1 select release_lock('mysqltest_lock'); release_lock('mysqltest_lock') 1 drop table t1; drop table if exists t1; create table t1 (a int) ENGINE=MEMORY; --> client 2 handler t1 open; ERROR HY000: Table storage engine for 't1' doesn't have this option --> client 1 drop table t1; drop table if exists t1; create table t1 (i int); connection: default lock tables t1 write; connection: flush flush tables with read lock;; connection: default alter table t1 add column j int; connection: insert insert into t1 values (1,2);; connection: default unlock tables; connection: flush select * from t1; i j unlock tables; select * from t1; i j 1 2 drop table t1; drop table if exists t1; create table t1 (i int); connection: default lock tables t1 write; connection: flush flush tables with read lock;; connection: default flush tables; unlock tables; drop table t1; drop table if exists t1,t2; create table t1 (a int); insert into t1 values (1); select get_lock('mysqltest_lock', 100); get_lock('mysqltest_lock', 100) 1 flush status; select * from t1 where get_lock('mysqltest_lock', 100); update t1 set a= 2; select release_lock('mysqltest_lock'); release_lock('mysqltest_lock') 1 a 1 select release_lock('mysqltest_lock'); release_lock('mysqltest_lock') 1 drop table t1; select @tlwa < @tlwb; @tlwa < @tlwb 1 End of 5.1 tests drop table if exists t1; create table t1 (i int); connection: default lock tables t1 write; connection: flush flush tables with read lock;; connection: default flush tables; drop table t1; # # Test for bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock". # drop table if exists t1; 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; # # Switching to connection 'con46272'. # The below ALTER TABLE statement should wait till transaction # in connection 'default' is complete and then succeed. # It should not deadlock or fail with ER_LOCK_DEADLOCK error. # Sending: alter table t1 add column c4 int;; # # Switching to connection 'default'. # Wait until the above ALTER TABLE gets blocked because this # connection holds SW metadata lock on table to be altered. # The below statement should succeed. It should not # deadlock or end with ER_LOCK_DEADLOCK error. update t1 set c3=c3+1 where c2=4; # Unblock ALTER TABLE by committing transaction. commit; # # Switching to connection 'con46272'. # Reaping ALTER TABLE. # # Switching to connection 'default'. drop table t1; # # Bug#47249 assert in MDL_global_lock::is_lock_type_compatible # DROP TABLE IF EXISTS t1; DROP VIEW IF EXISTS v1; # # Test 1: LOCK TABLES v1 WRITE, t1 READ; # # Thanks to the fact that we no longer allow DDL on tables # which are locked for write implicitly, the exact scenario # in which assert was failing is no longer repeatable. CREATE TABLE t1 ( f1 integer ); CREATE VIEW v1 AS SELECT f1 FROM t1 ; # Connection 2 LOCK TABLES v1 WRITE, t1 READ; FLUSH TABLE t1; # Connection 1 LOCK TABLES t1 WRITE; FLUSH TABLE t1; UNLOCK TABLES; DROP TABLE t1; DROP VIEW v1; # # Test 2: LOCK TABLES t1 WRITE, v1 READ; # CREATE TABLE t1 ( f1 integer ); CREATE VIEW v1 AS SELECT f1 FROM t1 ; # Connection 2 LOCK TABLES t1 WRITE, v1 READ; FLUSH TABLE t1; # Connection 1 LOCK TABLES t1 WRITE; FLUSH TABLE t1; DROP TABLE t1; DROP VIEW v1; # # Test for bug #50913 "Deadlock between open_and_lock_tables_derived # and MDL". Also see additional coverage in mdl_sync.test. # drop table if exists t1; drop view if exists v1; create table t1 (i int); create view v1 as select i from t1; begin; select * from t1; i # Switching to connection 'con50913'. # Sending: alter table t1 add column j int; # Switching to connection 'default'. # Wait until ALTER TABLE gets blocked. # The below statement should try to acquire SW lock on 't1' # and therefore should get ER_LOCK_DEADLOCK error. Before # bug fix it acquired SR lock and hung on thr_lock.c lock. delete a from t1 as a where i = 1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction # Unblock ALTER TABLE. commit; # Switching to connection 'con50913'. # Reaping ALTER TABLE; # Switching to connection 'default'. begin; select * from v1; i # Switching to connection 'con50913'. # Sending: alter table t1 drop column j; # Switching to connection 'default'. # Wait until ALTER TABLE gets blocked. # The below statement should try to acquire SW lock on 't1' # and therefore should get ER_LOCK_DEADLOCK error. Before # bug fix it acquired SR lock and hung on thr_lock.c lock. insert into v1 values (1); ERROR 40001: Deadlock found when trying to get lock; try restarting transaction # Unblock ALTER TABLE. commit; # Switching to connection 'con50913'. # Reaping ALTER TABLE; # Switching to connection 'default'. drop view v1; drop table t1; # # Bug#45225 Locking: hang if drop table with no timeout # # These tests also provide function coverage for the # lock_wait_timeout server variable. # DROP TABLE IF EXISTS t1; CREATE TABLE t1 (id int); SET SESSION lock_wait_timeout= 1; # # Test 1: acquire exclusive lock # # Connection default START TRANSACTION; INSERT INTO t1 VALUES (1); # Connection 2 DROP TABLE t1; ERROR HY000: Lock wait timeout exceeded; try restarting transaction # Connection default COMMIT; # # Test 2: upgrade shared lock # # Connection default START TRANSACTION; SELECT * FROM t1; id 1 # Connection 2 ALTER TABLE t1 RENAME TO t2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction # Connection default COMMIT; # # Test 3: acquire shared lock # # Connection default LOCK TABLE t1 WRITE; # Connection 2 INSERT INTO t1(id) VALUES (2); ERROR HY000: Lock wait timeout exceeded; try restarting transaction # Connection default UNLOCK TABLES; # # Test 4: table level locks # # Connection default LOCK TABLE t1 READ; # Connection 2 INSERT INTO t1(id) VALUES(4); ERROR HY000: Lock wait timeout exceeded; try restarting transaction # Connection default UNLOCK TABLES; # # Test 5: Waiting on Table Definition Cache (TDC) # # Connection default LOCK TABLE t1 READ; # Connection con3 # Sending: FLUSH TABLES; # Connection con2 SELECT * FROM t1; ERROR HY000: Lock wait timeout exceeded; try restarting transaction # Connection default UNLOCK TABLES; # Connection con3 # Reaping: FLUSH TABLES # # Test 6: Timeouts in I_S queries # # Connection default CREATE TABLE t2 (id INT); LOCK TABLE t2 WRITE; # Connection con3 # Sending: DROP TABLE t1, t2; # Connection con2 SELECT table_name, table_comment FROM information_schema.tables WHERE table_schema= 'test' AND table_name= 't1'; table_name table_comment t1 Lock wait timeout exceeded; try restarting transaction Warnings: Warning 1205 Lock wait timeout exceeded; try restarting transaction # Connection default UNLOCK TABLES; # Connection con3 # Reaping: DROP TABLE t1, t2 # Connection default # Cleanup # # Test for bug #51134 "Crash in MDL_lock::destroy on a concurrent # DDL workload". # drop tables if exists t1, t2, t3; create table t3 (i int); # Switching to connection 'con1' # Lock 't3' so upcoming RENAME is blocked. lock table t3 read; # Switching to connection 'con2' # Remember ID for this connection. # Start statement which will try to acquire two instances # of X metadata lock on the same object. # Sending: rename tables t1 to t2, t2 to t3;; # Switching to connection 'default' # Wait until RENAME TABLE is blocked on table 't3'. # Kill RENAME TABLE. kill query ID; # Switching to connection 'con2' # RENAME TABLE should be aborted but should not crash. ERROR 70100: Query execution was interrupted # Switching to connection 'con1' unlock tables; # Switching to connection 'default' drop table t3; # # Test for the bug where upgradable metadata locks was acquired # even if the table to altered was temporary. # Bug found while working on the related bug #51240. # DROP TABLE IF EXISTS t1; CREATE TABLE t1 (id INT); LOCK TABLE t1 WRITE; # Connection con1 CREATE TEMPORARY TABLE t1 (id INT); ALTER TABLE t1 ADD COLUMN j INT; # Connection default UNLOCK TABLES; DROP TABLE t1; # # Test coverage for LOCK TABLES ... READ/WRITE # # Of course this functionality is well-covered by tests all # around the test suite. Still it is nice to have formal # coverage for LOCK TABLES in one place. # # We are going to check behavior for both InnoDB and MyISAM # 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); # # 1) LOCK TABLES READ explicitly locking table # # 1.a) Allows concurrent reads LOCK TABLE t1 READ, t2 READ; connect con1, localhost, root; SELECT * FROM t1; i 1 SELECT * FROM t2; i 1 connection default; UNLOCK TABLES; # # 1.b) Is allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2;; connect con2, localhost, root; # Wait until SELECT gets read lock and starts waiting for user lock # LOCK TABLES should not be blocked. LOCK TABLES t1 READ, t2 READ; UNLOCK TABLES; connection default; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 # # 1.c) Blocks concurrent modifications to table connection default; LOCK TABLE t1 READ, t2 READ; connection con1; # Sending: INSERT INTO t1 VALUES (1); connection default; # Wait until INSERT gets blocked connection con2; # Sending: INSERT INTO t2 VALUES (1); connection default; # Wait until INSERT gets blocked # Unblock INSERTs UNLOCK TABLES; connection con1; # Reap INSERT connection con2; # Reap INSERT connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 1.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES t1 READ;; connection default; # Wait until LOCK TABLES READ is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES READ UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 # # The below part of test also covers scenario in which bug #42147 # "Concurrent DML and LOCK TABLE ... READ for InnoDB table cause # warnings in errlog" occurred. # connection con1; # Sending: INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES t2 READ;; connection default; # Wait until LOCK TABLES READ is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES READ UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 1.e) LOCK TABLES READ which explicitly locks table is not blocked # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; i 1 connection con1; LOCK TABLES t1 READ; UNLOCK TABLES; connection default; COMMIT; BEGIN; SELECT * FROM t2; i 1 connection con1; LOCK TABLES t2 READ; UNLOCK TABLES; connection default; COMMIT; # # 1.f) LOCK TABLES READ which explicitly locks table is blocked # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; # Sending: LOCK TABLES t1 READ;; connection default; # Wait until LOCK TABLES READ is blocked due concurrent transaction # Unblock LOCK TABLES READ COMMIT; connection con1; # Reap LOCK TABLES READ UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; # Sending: LOCK TABLES t2 READ;; connection default; # Wait until LOCK TABLES READ is blocked due concurrent transaction # Unblock LOCK TABLES READ COMMIT; connection con1; # Reap LOCK TABLES READ UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 1.g) LOCK TABLES READ which explicitly locks table is compatible # with itself. LOCK TABLES t1 READ, t2 READ; connection con1; LOCK TABLES t1 READ, t2 READ; UNLOCK TABLES; connection default; UNLOCK TABLES; # # 1.h) LOCK TABLES READ which explicitly locks table is not compatible # with LOCK TABLE WRITE. LOCK TABLES t1 READ; connection con1; # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES t2 READ; connection con1; # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES t1 WRITE; connection con1; # Sending: LOCK TABLES t1 READ;; connection default; # Wait until LOCK TABLES READ is blocked # Unblock LOCK TABLES READ UNLOCK TABLES; connection con1; # Reap LOCK TABLES READ UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; # Sending: LOCK TABLES t2 READ;; connection default; # Wait until LOCK TABLES READ is blocked # Unblock LOCK TABLES READ UNLOCK TABLES; connection con1; # Reap LOCK TABLES READ UNLOCK TABLES; # # 2) LOCK TABLES WRITE explicitly locking table # # 2.a) Doesn't allow concurrent reads connection default; LOCK TABLE t1 WRITE; connection con1; # Sending: SELECT * FROM t1;; connection default; # Wait until SELECT gets blocked # Unblock SELECT UNLOCK TABLES; connection con1; # Reaping SELECT i 1 connection default; LOCK TABLE t2 WRITE; connection con1; # Sending: SELECT * FROM t2;; connection default; # Wait until SELECT gets blocked # Unblock SELECT UNLOCK TABLES; connection con1; # Reaping SELECT i 1 connection default; # # 2.b) Is not allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t1;; connection con2; # Wait until SELECT gets read lock and starts waiting for user lock # Sending: LOCK TABLES t1 WRITE;; connection default; UNLOCK TABLES; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLE WRITE UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t2;; connection con2; # Wait until SELECT gets read lock and starts waiting for user lock # Sending: LOCK TABLES t2 WRITE;; connection default; UNLOCK TABLES; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLE WRITE UNLOCK TABLES; # # 2.c) Blocks concurrent modifications to table connection default; LOCK TABLE t1 WRITE, t2 WRITE; connection con1; # Sending: INSERT INTO t1 VALUES (1); connection default; # Wait until INSERT gets blocked connection con2; # Sending: INSERT INTO t2 VALUES (1); connection default; # Wait until INSERT gets blocked # Unblock INSERTs UNLOCK TABLES; connection con1; # Reap INSERT connection con2; # Reap INSERT connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 2.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES WRITE UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES WRITE UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 2.e) LOCK TABLES WRITE which explicitly locks table is blocked # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; i 1 connection con1; # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; BEGIN; SELECT * FROM t2; i 1 connection con1; # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; # # 2.f) LOCK TABLES WRITE which explicitly locks table is blocked # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 2.g) LOCK TABLES WRITE which explicitly locks table is not compatible # with itself. LOCK TABLES t1 WRITE; connection con1; # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; # # 3) LOCK TABLES which locks table for read through view. # Case of main table in mergeable view. # # 3.a) Allows concurrent reads connection default; LOCK TABLE v1 READ, v2 READ; connection con1; SELECT * FROM t1; i 1 SELECT * FROM t2; i 1 connection default; UNLOCK TABLES; # # 3.b) Is allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2;; connection con2; # Wait until SELECT gets read lock and starts waiting for user lock # LOCK TABLES should not be blocked. LOCK TABLES v1 READ, v2 READ; UNLOCK TABLES; connection default; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 # # 3.c) Blocks concurrent modifications to table connection default; LOCK TABLE v1 READ, v2 READ; connection con1; # Sending: INSERT INTO t1 VALUES (1); connection default; # Wait until INSERT gets blocked connection con2; # Sending: INSERT INTO t2 VALUES (1); connection default; # Wait until INSERT gets blocked # Unblock INSERTs UNLOCK TABLES; connection con1; # Reap INSERT connection con2; # Reap INSERT connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 3.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES v1 READ;; connection default; # Wait until LOCK TABLES READ is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES READ UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES v2 READ;; connection default; # Wait until LOCK TABLES READ is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES READ UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 3.e) LOCK TABLES which locks table for read through view is not blocked # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; i 1 connection con1; LOCK TABLES v1 READ; UNLOCK TABLES; connection default; COMMIT; BEGIN; SELECT * FROM t2; i 1 connection con1; LOCK TABLES v2 READ; UNLOCK TABLES; connection default; COMMIT; # # 3.f) LOCK TABLES which locks table for read through view is blocked # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; # Sending: LOCK TABLES v1 READ;; connection default; # Wait until LOCK TABLES READ is blocked due concurrent transaction # Unblock LOCK TABLES READ COMMIT; connection con1; # Reap LOCK TABLES READ UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; # Sending: LOCK TABLES v2 READ;; connection default; # Wait until LOCK TABLES READ is blocked due concurrent transaction # Unblock LOCK TABLES READ COMMIT; connection con1; # Reap LOCK TABLES READ UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 3.g) LOCK TABLES READ which locks table for read through view is # 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; # # 3.h) LOCK TABLES READ which locks table for read through view is # not compatible with explicit LOCK TABLES WRITE on the same table. LOCK TABLES v1 READ; connection con1; # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES v2 READ; connection con1; # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES t1 WRITE; connection con1; # Sending: LOCK TABLES v1 READ;; connection default; # Wait until LOCK TABLES READ is blocked # Unblock LOCK TABLES READ UNLOCK TABLES; connection con1; # Reap LOCK TABLES READ UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; # Sending: LOCK TABLES v2 READ;; connection default; # Wait until LOCK TABLES READ is blocked # Unblock LOCK TABLES READ UNLOCK TABLES; connection con1; # Reap LOCK TABLES READ UNLOCK TABLES; # # 4) LOCK TABLES which locks table for read through mergeable view. # Case of table not from the main join. Such table will be locked # for read even though view is locked for write. # 4.a) Allows concurrent reads connection default; LOCK TABLES v3 WRITE, v4 WRITE; connection con1; SELECT * FROM t1; i 1 SELECT * FROM t2; i 1 connection default; UNLOCK TABLES; # # 4.b) Is allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2;; connection con2; # Wait until SELECT gets read lock and starts waiting for user lock # LOCK TABLES should not be blocked. LOCK TABLES v3 WRITE, v4 WRITE; UNLOCK TABLES; connection default; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 # # 4.c) Blocks concurrent modifications to table connection default; LOCK TABLES v3 WRITE, v4 WRITE; connection con1; # Sending: INSERT INTO t1 VALUES (1); connection default; # Wait until INSERT gets blocked connection con2; # Sending: INSERT INTO t2 VALUES (1); connection default; # Wait until INSERT gets blocked # Unblock INSERTs UNLOCK TABLES; connection con1; # Reap INSERT connection con2; # Reap INSERT connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 4.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES v3 WRITE;; connection default; # Wait until LOCK TABLES is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES v4 WRITE;; connection default; # Wait until LOCK TABLES is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 4.e) LOCK TABLES which locks table for read through view is not blocked # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; i 1 connection con1; LOCK TABLES v3 WRITE; UNLOCK TABLES; connection default; COMMIT; BEGIN; SELECT * FROM t2; i 1 connection con1; LOCK TABLES v4 WRITE; UNLOCK TABLES; connection default; COMMIT; # # 4.f) LOCK TABLES which locks table for read through view is blocked # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; # Sending: LOCK TABLES v3 WRITE;; connection default; # Wait until LOCK TABLES is blocked due concurrent transaction # Unblock LOCK TABLES COMMIT; connection con1; # Reap LOCK TABLES UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; # Sending: LOCK TABLES v4 WRITE;; connection default; # Wait until LOCK TABLES is blocked due concurrent transaction # Unblock LOCK TABLES COMMIT; connection con1; # Reap LOCK TABLES UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 4.g) LOCK TABLES which locks table for read through view is # 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; # # 4.h) LOCK TABLES which locks table for read through view is # not compatible with explicit LOCK TABLES WRITE on the same table. LOCK TABLES v3 WRITE; connection con1; # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES v4 WRITE; connection con1; # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES t1 WRITE; connection con1; # Sending: LOCK TABLES v3 WRITE;; connection default; # Wait until LOCK TABLES is blocked # Unblock LOCK TABLES UNLOCK TABLES; connection con1; # Reap LOCK TABLES UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; # Sending: LOCK TABLES v4 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES UNLOCK TABLES; connection con1; # Reap LOCK TABLES UNLOCK TABLES; # # 5) LOCK TABLES which locks tables for write through view # # 5.a) Doesn't allow concurrent reads connection default; LOCK TABLE v1 WRITE; connection con1; # Sending: SELECT * FROM t1;; connection default; # Wait until SELECT gets blocked # Unblock SELECT UNLOCK TABLES; connection con1; # Reaping SELECT i 1 connection default; LOCK TABLE v2 WRITE; connection con1; # Sending: SELECT * FROM t2;; connection default; # Wait until SELECT gets blocked # Unblock SELECT UNLOCK TABLES; connection con1; # Reaping SELECT i 1 connection default; # # 5.b) Is not allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t1;; connection con2; # Wait until SELECT gets read lock and starts waiting for user lock # Sending: LOCK TABLES v1 WRITE;; connection default; UNLOCK TABLES; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLE WRITE UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t2;; connection con2; # Wait until SELECT gets read lock and starts waiting for user lock # Sending: LOCK TABLES v2 WRITE;; connection default; UNLOCK TABLES; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLE WRITE UNLOCK TABLES; # # 5.c) Blocks concurrent modifications to table connection default; LOCK TABLE v1 WRITE, v2 WRITE; connection con1; # Sending: INSERT INTO t1 VALUES (1); connection default; # Wait until INSERT gets blocked connection con2; # Sending: INSERT INTO t2 VALUES (1); connection default; # Wait until INSERT gets blocked # Unblock INSERTs UNLOCK TABLES; connection con1; # Reap INSERT connection con2; # Reap INSERT connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 5.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES v1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES WRITE UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES v2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES WRITE UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 5.e) LOCK TABLES which locks table for write through view is blocked # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; i 1 connection con1; # Sending: LOCK TABLES v1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; BEGIN; SELECT * FROM t2; i 1 connection con1; # Sending: LOCK TABLES v2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; # # 5.f) LOCK TABLES which locks table for write through view is blocked # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; # Sending: LOCK TABLES v1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; # Sending: LOCK TABLES v2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 5.g) LOCK TABLES which locks table for write through view is not # compatible with LOCK TABLE WRITE. LOCK TABLES v1 WRITE; connection con1; # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES v2 WRITE; connection con1; # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; # # 6) LOCK TABLES which locks table for read through trigger. # # 6.a) Allows concurrent reads connection default; LOCK TABLES t5 WRITE, t6 WRITE; connection con1; SELECT * FROM t1; i 1 SELECT * FROM t2; i 1 connection default; UNLOCK TABLES; # # 6.b) Is allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t1, t2;; connection con2; # Wait until SELECT gets read lock and starts waiting for user lock # LOCK TABLES should not be blocked. LOCK TABLES v3 WRITE, t6 WRITE; UNLOCK TABLES; connection default; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 # # 6.c) Blocks concurrent modifications to table connection default; LOCK TABLES t5 WRITE, t6 WRITE; connection con1; # Sending: INSERT INTO t1 VALUES (1); connection default; # Wait until INSERT gets blocked connection con2; # Sending: INSERT INTO t2 VALUES (1); connection default; # Wait until INSERT gets blocked # Unblock INSERTs UNLOCK TABLES; connection con1; # Reap INSERT connection con2; # Reap INSERT connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 6.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES t5 WRITE;; connection default; # Wait until LOCK TABLES is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES t6 WRITE;; connection default; # Wait until LOCK TABLES is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 6.e) LOCK TABLES which locks table for read through trigger is not # blocked by concurrent transactions which read table. BEGIN; SELECT * FROM t1; i 1 connection con1; LOCK TABLES t5 WRITE; UNLOCK TABLES; connection default; COMMIT; BEGIN; SELECT * FROM t2; i 1 connection con1; LOCK TABLES t6 WRITE; UNLOCK TABLES; connection default; COMMIT; # # 6.f) LOCK TABLES which locks table for read through trigger is # blocked by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; # Sending: LOCK TABLES t5 WRITE;; connection default; # Wait until LOCK TABLES is blocked due concurrent transaction # Unblock LOCK TABLES COMMIT; connection con1; # Reap LOCK TABLES UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; # Sending: LOCK TABLES t6 WRITE;; connection default; # Wait until LOCK TABLES is blocked due concurrent transaction # Unblock LOCK TABLES COMMIT; connection con1; # Reap LOCK TABLES UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 6.g) LOCK TABLES which locks table for read through trigger is # 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; # # 6.h) LOCK TABLES which locks table for read through trigger is # not compatible with explicit LOCK TABLES WRITE on the same table. LOCK TABLES t5 WRITE; connection con1; # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES t6 WRITE; connection con1; # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES t1 WRITE; connection con1; # Sending: LOCK TABLES t5 WRITE;; connection default; # Wait until LOCK TABLES is blocked # Unblock LOCK TABLES UNLOCK TABLES; connection con1; # Reap LOCK TABLES UNLOCK TABLES; connection default; LOCK TABLES t2 WRITE; connection con1; # Sending: LOCK TABLES t6 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES UNLOCK TABLES; connection con1; # Reap LOCK TABLES UNLOCK TABLES; # # 7) LOCK TABLES which locks tables for write through trigger # # 7.a) Doesn't allow concurrent reads connection default; LOCK TABLE t7 WRITE; connection con1; # Sending: SELECT * FROM t1;; connection default; # Wait until SELECT gets blocked # Unblock SELECT UNLOCK TABLES; connection con1; # Reaping SELECT i 1 connection default; LOCK TABLE t8 WRITE; connection con1; # Sending: SELECT * FROM t2;; connection default; # Wait until SELECT gets blocked # Unblock SELECT UNLOCK TABLES; connection con1; # Reaping SELECT i 1 connection default; # # 7.b) Is not allowed concurrently to reads SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t1;; connection con2; # Wait until SELECT gets read lock and starts waiting for user lock # Sending: LOCK TABLES t7 WRITE;; connection default; UNLOCK TABLES; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLE WRITE UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Start read by sending SELECT: SELECT GET_LOCK('mysqltest_lock', 100) FROM t2;; connection con2; # Wait until SELECT gets read lock and starts waiting for user lock # Sending: LOCK TABLES t8 WRITE;; connection default; UNLOCK TABLES; # Unblock SELECT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping SELECT GET_LOCK('mysqltest_lock', 100) 1 SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLE WRITE UNLOCK TABLES; # # 7.c) Blocks concurrent modifications to table connection default; LOCK TABLE t7 WRITE, t8 WRITE; connection con1; # Sending: INSERT INTO t1 VALUES (1); connection default; # Wait until INSERT gets blocked connection con2; # Sending: INSERT INTO t2 VALUES (1); connection default; # Wait until INSERT gets blocked # Unblock INSERTs UNLOCK TABLES; connection con1; # Reap INSERT connection con2; # Reap INSERT connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 7.d) Is blocked by concurrent table modifications SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t1 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES t7 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES WRITE UNLOCK TABLES; connection default; SELECT GET_LOCK('mysqltest_lock', 100); GET_LOCK('mysqltest_lock', 100) 1 connection con1; # Sending: INSERT INTO t2 VALUES (GET_LOCK('mysqltest_lock', 100));; connection con2; # Wait until INSERT gets SW MDL lock and starts waiting for user lock # Sending: LOCK TABLES t8 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due to INSERT # Unblock INSERT. SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con1; # Reaping INSERT SELECT RELEASE_LOCK('mysqltest_lock'); RELEASE_LOCK('mysqltest_lock') 1 connection con2; # Reaping LOCK TABLES WRITE UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 7.e) LOCK TABLES which locks table for write through trigger is blocked # by concurrent transactions which read table. BEGIN; SELECT * FROM t1; i 1 connection con1; # Sending: LOCK TABLES t7 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; BEGIN; SELECT * FROM t2; i 1 connection con1; # Sending: LOCK TABLES t8 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; # # 7.f) LOCK TABLES which locks table for write through trigger is blocked # by concurrent transactions which modify table. BEGIN; INSERT INTO t1 VALUES (1); connection con1; # Sending: LOCK TABLES t7 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; BEGIN; INSERT INTO t2 VALUES (1); connection con1; # Sending: LOCK TABLES t8 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked due concurrent transaction # Unblock LOCK TABLES WRITE COMMIT; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; # Revert effects from INSERTs DELETE FROM t1 LIMIT 1; DELETE FROM t2 LIMIT 1; # # 7.g) LOCK TABLES which locks table for write through trigger is not # compatible with LOCK TABLE WRITE. LOCK TABLES t7 WRITE; connection con1; # Sending: LOCK TABLES t1 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; connection default; LOCK TABLES t8 WRITE; connection con1; # Sending: LOCK TABLES t2 WRITE;; connection default; # Wait until LOCK TABLES WRITE is blocked # Unblock LOCK TABLES WRITE UNLOCK TABLES; connection con1; # Reap LOCK TABLES WRITE UNLOCK TABLES; disconnect con1; disconnect con2; connection default; DROP VIEW v1, v2, v3, v4; DROP TABLES t1, t2, t3, t4, t5, t6, t7, t8; # # Test coverage for LOCK TABLES ... READ LOCAL # 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; # # 1) READ LOCAL is fully supported for MyISAM. # Concurrent inserts are allowed. # LOCK TABLE t1 READ LOCAL; connect con1, localhost, root; INSERT INTO t1 VALUES (1); # # Concurrent updates are blocked. # # Sending: UPDATE t1 SET i= 2; connection default; # Wait until UPDATE is blocked. UNLOCK TABLES; connection con1; # Reaping UPDATE. # # 2) READ LOCAL works even for mergeable views on # top of MyISAM tables. # connection default; LOCK TABLE v1 READ LOCAL; connection con1; INSERT INTO v1 VALUES (1); INSERT INTO t1 VALUES (3); # Concurrent updates are blocked. # Sending: UPDATE t1 SET i= 2; connection default; # Wait until UPDATE is blocked. UNLOCK TABLES; connection con1; # Reaping UPDATE. # # 3) READ LOCAL doesn't work for non-mergeable views on # top of MyISAM tables. # connection default; LOCK TABLE v2 READ LOCAL; connection con1; # Sending: INSERT INTO t1 VALUES (1); connection default; # Wait until INSERT is blocked. UNLOCK TABLES; connection con1; # Reaping INSERT. connection default; LOCK TABLE v2 READ LOCAL; connection con1; # Sending: UPDATE t1 SET i= 2;; connection default; # Wait until UPDATE is blocked. UNLOCK TABLES; connection con1; # Reaping UPDATE. # # 4) READ LOCAL locks are upgraded to simple READ locks # for InnoDB tables. So they block both concurrent inserts # and updates. # connection default; LOCK TABLE t2 READ LOCAL; connection con1; # Sending: INSERT INTO t2 VALUES (1); connection default; # Wait until INSERT is blocked. UNLOCK TABLES; connection con1; # Reaping INSERT. connection default; LOCK TABLE t2 READ LOCAL; connection con1; # Sending: UPDATE t2 SET i= 2;; connection default; # Wait until UPDATE is blocked. UNLOCK TABLES; connection con1; # Reaping UPDATE. # # 5) For mergeable views on top of InnoDB tables READ LOCAL locks are # upgraded to simple READ locks as well. # connection default; LOCK TABLE v3 READ LOCAL; connection con1; # Sending: INSERT INTO t2 VALUES (1); connection default; # Wait until INSERT is blocked. UNLOCK TABLES; connection con1; # Reaping INSERT. connection default; LOCK TABLE v3 READ LOCAL; connection con1; # Sending: UPDATE t2 SET i= 2;; connection default; # Wait until UPDATE is blocked. UNLOCK TABLES; connection con1; # Reaping UPDATE. connection default; disconnect con1; DROP VIEW v1, v2, v3; DROP TABLES t1, t2; SET @@global.concurrent_insert= @old_concurrent_insert; # # Test coverage for interaction between LOCK TABLE ... READ and # concurrent DML which uses LOW_PRIORITY and HIGH_PRIORITY clauses/ # concurrent DML which is executed in @@low_priority_updates=1 mode. # # 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); # # 1) Let us check that DML operations with LOW_PRIORITY clauses have # lower priority than pending LOCK TABLE ... READ, thus can't starve # it out. # # Acquire SW lock on the table, to create pending LOCK TABLE ... READ. BEGIN; INSERT INTO t1 VALUES (1); connect blocker, localhost, root; # Sending: LOCK TABLE t1 READ;; connection default; # Wait until LOCK TABLE READ gets blocked connect con_insert, localhost, root; # INSERT HIGH_PRIORITY should not get blocked INSERT HIGH_PRIORITY INTO t1 VALUES (1); # Sending: INSERT LOW_PRIORITY INTO t1 VALUES (1);; connection default; # Check that INSERT is blocked connect con_replace, localhost, root; # Sending: REPLACE LOW_PRIORITY INTO t1 VALUES (1);; connection default; # Check that REPLACE is blocked connect con_update, localhost, root; # Sending: UPDATE LOW_PRIORITY t1 SET i= 1;; connection default; # Check that UPDATE is blocked connect con_update_multi, localhost, root; # Sending: UPDATE LOW_PRIORITY t1 AS a, t1 AS b SET a.i= 1;; connection default; # Check that multi-UPDATE is blocked connect con_delete, localhost, root; # Sending: DELETE LOW_PRIORITY FROM t1 LIMIT 1;; connection default; # Check that DELETE is blocked connect con_delete_multi, localhost, root; # Sending: DELETE LOW_PRIORITY FROM a USING t1 AS a, t1 AS b;; connection default; # Check that multi-DELETE is blocked connect con_load, localhost, root; # Sending: LOAD DATA LOW_PRIORITY INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i);; connection default; # Check that LOAD DATA is blocked # # This should work even for views. # connect con_view, localhost, root; # Sending: DELETE LOW_PRIORITY FROM v1;; connection default; # Check that DELETE is blocked # # And when LOW_PRIORITY clause is used in trigger. # connect con_trigger, localhost, root; # Sending: INSERT INTO t2 VALUES (1);; connection default; # Check that INSERT in trigger is blocked # # And for MERGE tables # connect con_merge, localhost, root; # Sending: DELETE LOW_PRIORITY FROM tm LIMIT 1;; connection default; # Check that DELETE from MERGE table is blocked # Unblock LOCK TABLE .. READ COMMIT; connection blocker; # Reaping LOCK TABLE .. READ UNLOCK TABLES; # Reap all DML statements. connection con_insert; connection con_replace; connection con_update; connection con_update_multi; connection con_delete; connection con_delete_multi; connection con_load; connection con_view; connection con_trigger; connection con_merge; connection default; # # 2) Let us check that DML operations have lower priority than pending # LOCK TABLE ... READ when @@low_priority_updates mode is on. # # Acquire SW lock on the table, to create pending LOCK TABLE ... READ. BEGIN; INSERT INTO t1 VALUES (0); connection blocker; # Sending: LOCK TABLE t1 READ;; connection default; # Wait until LOCK TABLE READ gets blocked connection con_insert; SET @@session.low_priority_updates= 1; # INSERT HIGH_PRIORITY still should not get blocked INSERT HIGH_PRIORITY INTO t1 VALUES (1); # Sending: INSERT INTO t1 VALUES (1);; connection default; # Check that INSERT is blocked connection con_replace; SET @@session.low_priority_updates= 1; # Sending: REPLACE INTO t1 VALUES (1);; connection default; # Check that REPLACE is blocked connection con_update; SET @@session.low_priority_updates= 1; # Sending: UPDATE t1 SET i= 1;; connection default; # Check that UPDATE is blocked connection con_update_multi; SET @@session.low_priority_updates= 1; # Sending: UPDATE t1 AS a, t1 AS b SET a.i= 1;; connection default; # Check that multi-UPDATE is blocked connection con_delete; SET @@session.low_priority_updates= 1; # Sending: DELETE FROM t1 LIMIT 1;; connection default; # Check that DELETE is blocked connection con_delete_multi; SET @@session.low_priority_updates= 1; # Sending: DELETE FROM a USING t1 AS a, t1 AS b;; connection default; # Check that multi-DELETE is blocked connection con_load; SET @@session.low_priority_updates= 1; # Sending: LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1 (@dummy,i);; connection default; # Check that LOAD DATA is blocked connection con_view; SET @@session.low_priority_updates= 1; # Sending: DELETE FROM v1;; connection default; # Check that DELETE is blocked # # And when table used in trigger. # connection con_trigger; SET @@session.low_priority_updates= 1; # Sending: INSERT INTO t3 VALUES (1);; connection default; # Check that INSERT in trigger is blocked # # And for MERGE tables # connection con_merge; SET @@session.low_priority_updates= 1; # Sending: DELETE FROM tm LIMIT 1;; connection default; # Check that DELETE from MERGE table is blocked # Unblock LOCK TABLE .. READ COMMIT; connection blocker; # Reaping LOCK TABLE .. READ UNLOCK TABLES; # Reap all DML statements. connection con_insert; connection con_replace; connection con_update; connection con_update_multi; connection con_delete; connection con_delete_multi; connection con_load; connection con_view; connection con_trigger; connection con_merge; 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; # # Test for bug #11764618 "DEADLOCK WHEN DDL UNDER LOCK TABLES # WRITE, READ + PREPARE". # 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; count(*) 0 # Sending: insert into t3 values (1);; connection con2; # Wait until 'con1' acquires SR metadata lock on 't4' # and blocks on 't3'. Before WL#6671 waiting has happened # on THR_LOCK lock which led to deadlock. # Sending: rename table t2 to t0, t4 to t2, t0 to t4;; connection con3; # Wait until RENAME acquires X metadata lock on 't2' # and blocks on 't4'. # Sending: prepare stmt1 from 'select * from t1, t2';; connection default; # Wait until PREPARE acquires S metadata lock on 't1' # and blocks on 't2'. # This ALTER TABLE upgrades SNRW lock on t1 to X lock. # In the past this caused deadlock. alter table t1 add column j int; unlock tables; connection con1; # Reap INSERT commit; connection con2; # Reap RENAME connection con3; # Reap PREPARE connection default; disconnect con1; disconnect con2; disconnect con3; drop tables t1, t2, t3, t4;