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;
|
UNLOCK TABLES;
|
||||||
LOCK TABLES v1 WRITE;
|
LOCK TABLES v1 WRITE;
|
||||||
FLUSH TABLES v1;
|
FLUSH TABLES v1;
|
||||||
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
|
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
LOCK TABLES v1 READ;
|
LOCK TABLES v1 READ;
|
||||||
FLUSH TABLES t1;
|
FLUSH TABLES t1;
|
||||||
|
@ -136,7 +136,7 @@ select * from t1;
|
|||||||
ERROR HY000: Table 't1' was not locked with LOCK TABLES
|
ERROR HY000: Table 't1' was not locked with LOCK TABLES
|
||||||
unlock tables;
|
unlock tables;
|
||||||
create or replace view v_bug5719 as select * from t1;
|
create or replace view v_bug5719 as select * from t1;
|
||||||
lock tables v_bug5719 write;
|
lock tables v_bug5719 read;
|
||||||
select * from v_bug5719;
|
select * from v_bug5719;
|
||||||
a
|
a
|
||||||
|
|
||||||
@ -299,7 +299,7 @@ create table t2 (j int);
|
|||||||
#
|
#
|
||||||
# Try to perform DDL on table which is locked through view.
|
# Try to perform DDL on table which is locked through view.
|
||||||
create view v1 as select * from t2;
|
create view v1 as select * from t2;
|
||||||
lock tables t1 write, v1 write;
|
lock tables t1 write, v1 read;
|
||||||
flush table t2;
|
flush table t2;
|
||||||
ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
|
ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
|
||||||
drop table t2;
|
drop table t2;
|
||||||
|
@ -276,15 +276,14 @@ DROP VIEW IF EXISTS v1;
|
|||||||
#
|
#
|
||||||
# Test 1: LOCK TABLES v1 WRITE, t1 READ;
|
# 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 TABLE t1 ( f1 integer );
|
||||||
CREATE VIEW v1 AS SELECT f1 FROM t1 ;
|
CREATE VIEW v1 AS SELECT f1 FROM t1 ;
|
||||||
|
# Connection 2
|
||||||
LOCK TABLES v1 WRITE, t1 READ;
|
LOCK TABLES v1 WRITE, t1 READ;
|
||||||
FLUSH TABLE t1;
|
FLUSH TABLE t1;
|
||||||
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
|
# Connection 1
|
||||||
UNLOCK TABLES;
|
LOCK TABLES t1 WRITE;
|
||||||
|
FLUSH TABLE t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
#
|
#
|
||||||
|
@ -648,9 +648,6 @@ set debug_sync= 'RESET';
|
|||||||
set @old_general_log = @@global.general_log;
|
set @old_general_log = @@global.general_log;
|
||||||
set @@global.general_log= OFF;
|
set @@global.general_log= OFF;
|
||||||
create table t1 (i int) engine=InnoDB;
|
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);
|
insert into t1 values (1);
|
||||||
# Prepare user lock which will be used for resuming execution of
|
# Prepare user lock which will be used for resuming execution of
|
||||||
# the first statement after it acquires TL_WRITE_ALLOW_WRITE lock.
|
# 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'.
|
# acquiring lock for the the first instance of 't1'.
|
||||||
set debug_sync= 'now WAIT_FOR parked';
|
set debug_sync= 'now WAIT_FOR parked';
|
||||||
# Send LOCK TABLE statement which will try to get TL_WRITE lock on 't1':
|
# 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'.
|
# Switch to connection 'default'.
|
||||||
# Wait until this LOCK TABLES statement starts waiting for table lock.
|
# Wait until this LOCK TABLES statement starts waiting for table lock.
|
||||||
# Allow SELECT ... FOR UPDATE to resume.
|
# Allow SELECT ... FOR UPDATE to resume.
|
||||||
@ -703,7 +700,6 @@ unlock tables;
|
|||||||
# Do clean-up.
|
# Do clean-up.
|
||||||
set debug_sync= 'RESET';
|
set debug_sync= 'RESET';
|
||||||
set @@global.general_log= @old_general_log;
|
set @@global.general_log= @old_general_log;
|
||||||
drop view v1;
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
#
|
||||||
# Bug#50821 Deadlock between LOCK TABLES and ALTER TABLE
|
# 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('4','1','1');
|
||||||
INSERT INTO t1 VALUES('5','1','1');
|
INSERT INTO t1 VALUES('5','1','1');
|
||||||
INSERT INTO t1 VALUES('6','1','1');
|
INSERT INTO t1 VALUES('6','1','1');
|
||||||
LOCK TABLE v1 WRITE;
|
LOCK TABLE v1 READ;
|
||||||
** Connection con1 **
|
** Connection con1 **
|
||||||
INSERT DELAYED INTO t1 VALUES('7','1','1');
|
INSERT DELAYED INTO t1 VALUES('7','1','1');
|
||||||
INSERT DELAYED INTO t1 VALUES('8','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('4');
|
||||||
INSERT INTO t1 VALUES('5');
|
INSERT INTO t1 VALUES('5');
|
||||||
INSERT INTO t1 VALUES('6');
|
INSERT INTO t1 VALUES('6');
|
||||||
LOCK TABLE v1 WRITE;
|
LOCK TABLE v1 READ;
|
||||||
** Connection con1 **
|
** Connection con1 **
|
||||||
Asynchronous execute
|
Asynchronous execute
|
||||||
INSERT DELAYED INTO t1 VALUES('7');
|
INSERT DELAYED INTO t1 VALUES('7');
|
||||||
|
@ -20,7 +20,7 @@ INSERT INTO t1 VALUES('3');
|
|||||||
INSERT INTO t1 VALUES('4');
|
INSERT INTO t1 VALUES('4');
|
||||||
INSERT INTO t1 VALUES('5');
|
INSERT INTO t1 VALUES('5');
|
||||||
INSERT INTO t1 VALUES('6');
|
INSERT INTO t1 VALUES('6');
|
||||||
LOCK TABLE v1 WRITE;
|
LOCK TABLE v1 WRITE CONCURRENT;
|
||||||
** Connection con1 **
|
** Connection con1 **
|
||||||
** Asynchronous Execution **
|
** Asynchronous Execution **
|
||||||
UPDATE t1 SET a = CONCAT(a,"-updated");|
|
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('4');
|
||||||
INSERT INTO t1 VALUES('5');
|
INSERT INTO t1 VALUES('5');
|
||||||
INSERT INTO t1 VALUES('6');
|
INSERT INTO t1 VALUES('6');
|
||||||
LOCK TABLE v1 WRITE;
|
LOCK TABLE v1 READ;
|
||||||
** Connection con1 **
|
** Connection con1 **
|
||||||
** Asynchronous Execution **
|
** Asynchronous Execution **
|
||||||
UPDATE t1 SET a = CONCAT(a,"-updated");|
|
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('5','1','1');
|
||||||
INSERT INTO t1 VALUES('6','1','1');
|
INSERT INTO t1 VALUES('6','1','1');
|
||||||
|
|
||||||
LOCK TABLE v1 WRITE;
|
LOCK TABLE v1 READ;
|
||||||
|
|
||||||
--echo ** Connection con1 **
|
--echo ** Connection con1 **
|
||||||
connection con1;
|
connection con1;
|
||||||
@ -110,9 +110,8 @@ delimiter ;|
|
|||||||
--echo ** Connection con0 **
|
--echo ** Connection con0 **
|
||||||
connection con0;
|
connection con0;
|
||||||
let $wait_condition=
|
let $wait_condition=
|
||||||
SELECT variable_value > @@global.delayed_insert_limit
|
SELECT COUNT(*) = 1 FROM information_schema.processlist
|
||||||
FROM information_schema.global_status
|
WHERE state = 'Waiting for table level lock' AND user='delayed';
|
||||||
WHERE variable_name like 'Not_flushed_delayed_rows';
|
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
let $my_select= SELECT COUNT(*) FROM t1;
|
let $my_select= SELECT COUNT(*) FROM t1;
|
||||||
send;
|
send;
|
||||||
@ -137,13 +136,6 @@ connection con0;
|
|||||||
--echo Asynchronous "reap" result
|
--echo Asynchronous "reap" result
|
||||||
--echo The next result suffers from
|
--echo The next result suffers from
|
||||||
--echo '# Bug#35386 insert delayed inserts 1 + limit rows instead of just limit rows'
|
--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;
|
reap;
|
||||||
|
|
||||||
--echo ** Connection default **
|
--echo ** Connection default **
|
||||||
@ -173,7 +165,7 @@ INSERT INTO t1 VALUES('4');
|
|||||||
INSERT INTO t1 VALUES('5');
|
INSERT INTO t1 VALUES('5');
|
||||||
INSERT INTO t1 VALUES('6');
|
INSERT INTO t1 VALUES('6');
|
||||||
|
|
||||||
LOCK TABLE v1 WRITE;
|
LOCK TABLE v1 READ;
|
||||||
|
|
||||||
--echo ** Connection con1 **
|
--echo ** Connection con1 **
|
||||||
connection con1;
|
connection con1;
|
||||||
@ -204,8 +196,8 @@ delimiter ;|
|
|||||||
--echo ** Connection con0 **
|
--echo ** Connection con0 **
|
||||||
connection con0;
|
connection con0;
|
||||||
let $wait_condition=
|
let $wait_condition=
|
||||||
SELECT variable_value > 0 FROM information_schema.global_status
|
SELECT COUNT(*) = 1 FROM information_schema.processlist
|
||||||
WHERE variable_name like 'Not_flushed_delayed_rows';
|
WHERE state = 'Waiting for table level lock' AND user='delayed';
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
--echo Asynchronous execute
|
--echo Asynchronous execute
|
||||||
# Due to performance and server behaveiour the test observes values between 6 and 22.
|
# 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('5');
|
||||||
INSERT INTO t1 VALUES('6');
|
INSERT INTO t1 VALUES('6');
|
||||||
|
|
||||||
LOCK TABLE v1 WRITE;
|
LOCK TABLE v1 WRITE CONCURRENT;
|
||||||
|
|
||||||
--echo ** Connection con1 **
|
--echo ** Connection con1 **
|
||||||
connection con1;
|
connection con1;
|
||||||
@ -144,7 +144,7 @@ INSERT INTO t1 VALUES('4');
|
|||||||
INSERT INTO t1 VALUES('5');
|
INSERT INTO t1 VALUES('5');
|
||||||
INSERT INTO t1 VALUES('6');
|
INSERT INTO t1 VALUES('6');
|
||||||
|
|
||||||
LOCK TABLE v1 WRITE;
|
LOCK TABLE v1 READ;
|
||||||
|
|
||||||
--echo ** Connection con1 **
|
--echo ** Connection con1 **
|
||||||
connection con1;
|
connection con1;
|
||||||
|
@ -724,7 +724,6 @@ FLUSH TABLES v1;
|
|||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
LOCK TABLES v1 WRITE;
|
LOCK TABLES v1 WRITE;
|
||||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
|
||||||
FLUSH TABLES v1;
|
FLUSH TABLES v1;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ drop view v_bug5719;
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
unlock tables;
|
unlock tables;
|
||||||
create or replace view v_bug5719 as select * from t1;
|
create or replace view v_bug5719 as select * from t1;
|
||||||
lock tables v_bug5719 write;
|
lock tables v_bug5719 read;
|
||||||
select * from v_bug5719;
|
select * from v_bug5719;
|
||||||
--echo
|
--echo
|
||||||
--echo Allowed to use an underlying table under LOCK TABLES <view>
|
--echo Allowed to use an underlying table under LOCK TABLES <view>
|
||||||
@ -370,7 +370,7 @@ create table t2 (j int);
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # Try to perform DDL on table which is locked through view.
|
--echo # Try to perform DDL on table which is locked through view.
|
||||||
create view v1 as select * from t2;
|
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
|
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||||
flush table t2;
|
flush table t2;
|
||||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||||
|
@ -771,17 +771,21 @@ DROP VIEW IF EXISTS v1;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # Test 1: LOCK TABLES v1 WRITE, t1 READ;
|
--echo # Test 1: LOCK TABLES v1 WRITE, t1 READ;
|
||||||
--echo #
|
--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 TABLE t1 ( f1 integer );
|
||||||
CREATE VIEW v1 AS SELECT f1 FROM t1 ;
|
CREATE VIEW v1 AS SELECT f1 FROM t1 ;
|
||||||
|
|
||||||
|
--echo # Connection 2
|
||||||
|
connect (con2,localhost,root);
|
||||||
LOCK TABLES v1 WRITE, t1 READ;
|
LOCK TABLES v1 WRITE, t1 READ;
|
||||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
|
||||||
FLUSH TABLE t1;
|
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
|
# Cleanup
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
@ -909,9 +909,6 @@ set @old_general_log = @@global.general_log;
|
|||||||
set @@global.general_log= OFF;
|
set @@global.general_log= OFF;
|
||||||
|
|
||||||
create table t1 (i int) engine=InnoDB;
|
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);
|
insert into t1 values (1);
|
||||||
--echo # Prepare user lock which will be used for resuming execution of
|
--echo # Prepare user lock which will be used for resuming execution of
|
||||||
--echo # the first statement after it acquires TL_WRITE_ALLOW_WRITE lock.
|
--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'.
|
--echo # acquiring lock for the the first instance of 't1'.
|
||||||
set debug_sync= 'now WAIT_FOR parked';
|
set debug_sync= 'now WAIT_FOR parked';
|
||||||
--echo # Send LOCK TABLE statement which will try to get TL_WRITE lock on 't1':
|
--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'.
|
--echo # Switch to connection 'default'.
|
||||||
connection default;
|
connection default;
|
||||||
--echo # Wait until this LOCK TABLES statement starts waiting for table lock.
|
--echo # Wait until this LOCK TABLES statement starts waiting for table lock.
|
||||||
let $wait_condition= select count(*)= 1 from information_schema.processlist
|
let $wait_condition= select count(*)= 1 from information_schema.processlist
|
||||||
where state= 'Waiting for table level lock' and
|
where state= 'Waiting for table level lock' and
|
||||||
info='lock table v1 write';
|
info='lock table t1 write concurrent';
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
--echo # Allow SELECT ... FOR UPDATE to resume.
|
--echo # Allow SELECT ... FOR UPDATE to resume.
|
||||||
--echo # Since it already has TL_WRITE_ALLOW_WRITE lock on the first instance
|
--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;
|
disconnect con_bug45143_3;
|
||||||
set debug_sync= 'RESET';
|
set debug_sync= 'RESET';
|
||||||
set @@global.general_log= @old_general_log;
|
set @@global.general_log= @old_general_log;
|
||||||
drop view v1;
|
|
||||||
drop table t1;
|
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)
|
for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local)
|
||||||
{
|
{
|
||||||
tbl->lock_type= table->lock_type;
|
tbl->lock_type= table->lock_type;
|
||||||
tbl->mdl_request.set_type((tbl->lock_type >= TL_WRITE_ALLOW_WRITE) ?
|
tbl->mdl_request.set_type(table->mdl_request.type);
|
||||||
MDL_SHARED_WRITE : MDL_SHARED_READ);
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
If the view is mergeable, we might want to
|
If the view is mergeable, we might want to
|
||||||
|
Reference in New Issue
Block a user