mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
A fix and a test case for Bug#51710 FLUSH TABLES <view> WITH READ
LOCK kills the server. Prohibit FLUSH TABLES WITH READ LOCK application to views or temporary tables. Fix a subtle bug in the implementation when we actually did not remove table share objects from the table cache after acquiring exclusive locks. mysql-test/r/flush.result: Update results (Bug#51710) mysql-test/t/flush.test: Add a test case for Bug#51710. sql/sql_parse.cc: Fix Bug#51710 "FLUSH TABLES <view> WITH READ LOCK killes the server. Ensure we don't open views and temporary tables. Fix a yet another bug in the implementation which did not actually remove the tables from cache after acquiring exclusive locks.
This commit is contained in:
@@ -207,3 +207,30 @@ insert into t2 (a) values (3);
|
||||
unlock tables;
|
||||
# --> connection con1
|
||||
drop table t1, t2, t3;
|
||||
#
|
||||
# Bug#51710 FLUSH TABLES <view> WITH READ LOCK kills the server
|
||||
#
|
||||
drop view if exists v1, v2, v3;
|
||||
drop table if exists t1, v1;
|
||||
create table t1 (a int);
|
||||
create view v1 as select 1;
|
||||
create view v2 as select * from t1;
|
||||
create view v3 as select * from v2;
|
||||
flush table v1, v2, v3 with read lock;
|
||||
ERROR HY000: 'test.v1' is not BASE TABLE
|
||||
flush table v1 with read lock;
|
||||
ERROR HY000: 'test.v1' is not BASE TABLE
|
||||
flush table v2 with read lock;
|
||||
ERROR HY000: 'test.v2' is not BASE TABLE
|
||||
flush table v3 with read lock;
|
||||
ERROR HY000: 'test.v3' is not BASE TABLE
|
||||
create temporary table v1 (a int);
|
||||
flush table v1 with read lock;
|
||||
ERROR HY000: 'test.v1' is not BASE TABLE
|
||||
drop view v1;
|
||||
create table v1 (a int);
|
||||
flush table v1 with read lock;
|
||||
drop temporary table v1;
|
||||
unlock tables;
|
||||
drop view v2, v3;
|
||||
drop table t1, v1;
|
||||
|
||||
@@ -324,3 +324,34 @@ disconnect con1;
|
||||
--source include/wait_until_disconnected.inc
|
||||
connection default;
|
||||
drop table t1, t2, t3;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#51710 FLUSH TABLES <view> WITH READ LOCK kills the server
|
||||
--echo #
|
||||
--disable_warnings
|
||||
drop view if exists v1, v2, v3;
|
||||
drop table if exists t1, v1;
|
||||
--enable_warnings
|
||||
create table t1 (a int);
|
||||
create view v1 as select 1;
|
||||
create view v2 as select * from t1;
|
||||
create view v3 as select * from v2;
|
||||
|
||||
--error ER_WRONG_OBJECT
|
||||
flush table v1, v2, v3 with read lock;
|
||||
--error ER_WRONG_OBJECT
|
||||
flush table v1 with read lock;
|
||||
--error ER_WRONG_OBJECT
|
||||
flush table v2 with read lock;
|
||||
--error ER_WRONG_OBJECT
|
||||
flush table v3 with read lock;
|
||||
create temporary table v1 (a int);
|
||||
--error ER_WRONG_OBJECT
|
||||
flush table v1 with read lock;
|
||||
drop view v1;
|
||||
create table v1 (a int);
|
||||
flush table v1 with read lock;
|
||||
drop temporary table v1;
|
||||
unlock tables;
|
||||
drop view v2, v3;
|
||||
drop table t1, v1;
|
||||
|
||||
@@ -1631,6 +1631,14 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
||||
- you can't flush WITH READ LOCK a non-existent table
|
||||
- you can't flush WITH READ LOCK under LOCK TABLES
|
||||
- currently incompatible with the GRL (@todo: fix)
|
||||
|
||||
Effect on views and temporary tables.
|
||||
------------------------------------
|
||||
You can only apply this command to existing base tables.
|
||||
If a view with such name exists, ER_WRONG_OBJECT is returned.
|
||||
If a temporary table with such name exists, it's ignored:
|
||||
if there is a base table, it's used, otherwise ER_NO_SUCH_TABLE
|
||||
is returned.
|
||||
*/
|
||||
|
||||
static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
|
||||
@@ -1665,6 +1673,21 @@ static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
|
||||
if (lock_table_names(thd, all_tables))
|
||||
goto error;
|
||||
|
||||
for (table_list= all_tables; table_list;
|
||||
table_list= table_list->next_global)
|
||||
{
|
||||
/* Remove the table from cache. */
|
||||
mysql_mutex_lock(&LOCK_open);
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
|
||||
table_list->db,
|
||||
table_list->table_name);
|
||||
mysql_mutex_unlock(&LOCK_open);
|
||||
|
||||
/* Skip views and temporary tables. */
|
||||
table_list->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
|
||||
table_list->open_type= OT_BASE_ONLY; /* Ignore temporary tables. */
|
||||
}
|
||||
|
||||
if (open_and_lock_tables(thd, all_tables, FALSE,
|
||||
MYSQL_OPEN_HAS_MDL_LOCK,
|
||||
&lock_tables_prelocking_strategy) ||
|
||||
|
||||
Reference in New Issue
Block a user