mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user