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;
