Commit 6472c5c0 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-15890 Strange error message if you try to FLUSH TABLES <view> after LOCK TABLES <view>.

LOCK view WRITE shouldn't block FLUSH view.
So we set the view's mdl_request type to it's tables.
parent 1a893563
......@@ -508,7 +508,6 @@ ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
UNLOCK TABLES;
LOCK TABLES v1 WRITE;
FLUSH TABLES v1;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
UNLOCK TABLES;
LOCK TABLES v1 READ;
FLUSH TABLES t1;
......
......@@ -136,7 +136,7 @@ select * from t1;
ERROR HY000: Table 't1' was not locked with LOCK TABLES
unlock tables;
create or replace view v_bug5719 as select * from t1;
lock tables v_bug5719 write;
lock tables v_bug5719 read;
select * from v_bug5719;
a
......@@ -299,7 +299,7 @@ create table t2 (j int);
#
# Try to perform DDL on table which is locked through view.
create view v1 as select * from t2;
lock tables t1 write, v1 write;
lock tables t1 write, v1 read;
flush table t2;
ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
drop table t2;
......
......@@ -276,15 +276,14 @@ 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;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
UNLOCK TABLES;
# Connection 1
LOCK TABLES t1 WRITE;
FLUSH TABLE t1;
DROP TABLE t1;
DROP VIEW v1;
#
......
......@@ -648,9 +648,6 @@ set debug_sync= 'RESET';
set @old_general_log = @@global.general_log;
set @@global.general_log= OFF;
create table t1 (i int) engine=InnoDB;
# We have to use view in order to make LOCK TABLES avoid
# acquiring SNRW metadata lock on table.
create view v1 as select * from t1;
insert into t1 values (1);
# Prepare user lock which will be used for resuming execution of
# the first statement after it acquires TL_WRITE_ALLOW_WRITE lock.
......@@ -673,7 +670,7 @@ select count(*) > 0 from t1 as a, t1 as b for update;;
# acquiring lock for the the first instance of 't1'.
set debug_sync= 'now WAIT_FOR parked';
# Send LOCK TABLE statement which will try to get TL_WRITE lock on 't1':
lock table v1 write;;
lock table t1 write concurrent;;
# Switch to connection 'default'.
# Wait until this LOCK TABLES statement starts waiting for table lock.
# Allow SELECT ... FOR UPDATE to resume.
......@@ -703,7 +700,6 @@ unlock tables;
# Do clean-up.
set debug_sync= 'RESET';
set @@global.general_log= @old_general_log;
drop view v1;
drop table t1;
#
# Bug#50821 Deadlock between LOCK TABLES and ALTER TABLE
......
......@@ -13,7 +13,7 @@ INSERT INTO t1 VALUES('3','1','1');
INSERT INTO t1 VALUES('4','1','1');
INSERT INTO t1 VALUES('5','1','1');
INSERT INTO t1 VALUES('6','1','1');
LOCK TABLE v1 WRITE;
LOCK TABLE v1 READ;
** Connection con1 **
INSERT DELAYED INTO t1 VALUES('7','1','1');
INSERT DELAYED INTO t1 VALUES('8','1','1');
......@@ -82,7 +82,7 @@ INSERT INTO t1 VALUES('3');
INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
LOCK TABLE v1 WRITE;
LOCK TABLE v1 READ;
** Connection con1 **
Asynchronous execute
INSERT DELAYED INTO t1 VALUES('7');
......
......@@ -20,7 +20,7 @@ INSERT INTO t1 VALUES('3');
INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
LOCK TABLE v1 WRITE;
LOCK TABLE v1 WRITE CONCURRENT;
** Connection con1 **
** Asynchronous Execution **
UPDATE t1 SET a = CONCAT(a,"-updated");|
......@@ -56,7 +56,7 @@ INSERT INTO t1 VALUES('3');
INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
LOCK TABLE v1 WRITE;
LOCK TABLE v1 READ;
** Connection con1 **
** Asynchronous Execution **
UPDATE t1 SET a = CONCAT(a,"-updated");|
......
......@@ -61,7 +61,7 @@ INSERT INTO t1 VALUES('4','1','1');
INSERT INTO t1 VALUES('5','1','1');
INSERT INTO t1 VALUES('6','1','1');
LOCK TABLE v1 WRITE;
LOCK TABLE v1 READ;
--echo ** Connection con1 **
connection con1;
......@@ -110,9 +110,8 @@ delimiter ;|
--echo ** Connection con0 **
connection con0;
let $wait_condition=
SELECT variable_value > @@global.delayed_insert_limit
FROM information_schema.global_status
WHERE variable_name like 'Not_flushed_delayed_rows';
SELECT COUNT(*) = 1 FROM information_schema.processlist
WHERE state = 'Waiting for table level lock' AND user='delayed';
--source include/wait_condition.inc
let $my_select= SELECT COUNT(*) FROM t1;
send;
......@@ -137,13 +136,6 @@ connection con0;
--echo Asynchronous "reap" result
--echo The next result suffers from
--echo '# Bug#35386 insert delayed inserts 1 + limit rows instead of just limit rows'
#
# on UNLOCK TABLES both SELECT in the con0 and delayed insert thread in the
# con1 were awaken. There's no FIFO for TL_WRITE_DELAYED and TL_READ,
# so either the first delayed_insert_limit rows will be inserted
# before select (which will see 21 row) or select will go first (and see 6 rows)
#
--replace_result 6 21
reap;
--echo ** Connection default **
......@@ -173,7 +165,7 @@ INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
LOCK TABLE v1 WRITE;
LOCK TABLE v1 READ;
--echo ** Connection con1 **
connection con1;
......@@ -204,8 +196,8 @@ delimiter ;|
--echo ** Connection con0 **
connection con0;
let $wait_condition=
SELECT variable_value > 0 FROM information_schema.global_status
WHERE variable_name like 'Not_flushed_delayed_rows';
SELECT COUNT(*) = 1 FROM information_schema.processlist
WHERE state = 'Waiting for table level lock' AND user='delayed';
--source include/wait_condition.inc
--echo Asynchronous execute
# Due to performance and server behaveiour the test observes values between 6 and 22.
......
......@@ -70,7 +70,7 @@ INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
LOCK TABLE v1 WRITE;
LOCK TABLE v1 WRITE CONCURRENT;
--echo ** Connection con1 **
connection con1;
......@@ -144,7 +144,7 @@ INSERT INTO t1 VALUES('4');
INSERT INTO t1 VALUES('5');
INSERT INTO t1 VALUES('6');
LOCK TABLE v1 WRITE;
LOCK TABLE v1 READ;
--echo ** Connection con1 **
connection con1;
......
......@@ -724,7 +724,6 @@ FLUSH TABLES v1;
UNLOCK TABLES;
LOCK TABLES v1 WRITE;
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
FLUSH TABLES v1;
UNLOCK TABLES;
......
......@@ -192,7 +192,7 @@ drop view v_bug5719;
select * from t1;
unlock tables;
create or replace view v_bug5719 as select * from t1;
lock tables v_bug5719 write;
lock tables v_bug5719 read;
select * from v_bug5719;
--echo
--echo Allowed to use an underlying table under LOCK TABLES <view>
......@@ -370,7 +370,7 @@ create table t2 (j int);
--echo #
--echo # Try to perform DDL on table which is locked through view.
create view v1 as select * from t2;
lock tables t1 write, v1 write;
lock tables t1 write, v1 read;
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
flush table t2;
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
......
......@@ -771,17 +771,21 @@ DROP VIEW IF EXISTS v1;
--echo #
--echo # Test 1: LOCK TABLES v1 WRITE, t1 READ;
--echo #
--echo # Thanks to the fact that we no longer allow DDL on tables
--echo # which are locked for write implicitly, the exact scenario
--echo # in which assert was failing is no longer repeatable.
CREATE TABLE t1 ( f1 integer );
CREATE VIEW v1 AS SELECT f1 FROM t1 ;
--echo # Connection 2
connect (con2,localhost,root);
LOCK TABLES v1 WRITE, t1 READ;
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
FLUSH TABLE t1;
UNLOCK TABLES;
disconnect con2;
--source include/wait_until_disconnected.inc
--echo # Connection 1
connection default;
LOCK TABLES t1 WRITE;
FLUSH TABLE t1; # Assertion happened here
# Cleanup
DROP TABLE t1;
......
......@@ -909,9 +909,6 @@ set @old_general_log = @@global.general_log;
set @@global.general_log= OFF;
create table t1 (i int) engine=InnoDB;
--echo # We have to use view in order to make LOCK TABLES avoid
--echo # acquiring SNRW metadata lock on table.
create view v1 as select * from t1;
insert into t1 values (1);
--echo # Prepare user lock which will be used for resuming execution of
--echo # the first statement after it acquires TL_WRITE_ALLOW_WRITE lock.
......@@ -942,14 +939,14 @@ connection con_bug45143_3;
--echo # acquiring lock for the the first instance of 't1'.
set debug_sync= 'now WAIT_FOR parked';
--echo # Send LOCK TABLE statement which will try to get TL_WRITE lock on 't1':
--send lock table v1 write;
--send lock table t1 write concurrent;
--echo # Switch to connection 'default'.
connection default;
--echo # Wait until this LOCK TABLES statement starts waiting for table lock.
let $wait_condition= select count(*)= 1 from information_schema.processlist
where state= 'Waiting for table level lock' and
info='lock table v1 write';
info='lock table t1 write concurrent';
--source include/wait_condition.inc
--echo # Allow SELECT ... FOR UPDATE to resume.
--echo # Since it already has TL_WRITE_ALLOW_WRITE lock on the first instance
......@@ -993,7 +990,6 @@ disconnect con_bug45143_2;
disconnect con_bug45143_3;
set debug_sync= 'RESET';
set @@global.general_log= @old_general_log;
drop view v1;
drop table t1;
......
......@@ -1534,8 +1534,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local)
{
tbl->lock_type= table->lock_type;
tbl->mdl_request.set_type((tbl->lock_type >= TL_WRITE_ALLOW_WRITE) ?
MDL_SHARED_WRITE : MDL_SHARED_READ);
tbl->mdl_request.set_type(table->mdl_request.type);
}
/*
If the view is mergeable, we might want to
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment