mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fix for bug #55273 "FLUSH TABLE tm WITH READ LOCK for Merge
table causes assert failure". Attempting to use FLUSH TABLE table_list WITH READ LOCK statement for a MERGE table led to an assertion failure if one of its children was not present in the list of tables to be flushed. The problem was not visible in non-debug builds. The assertion failure was caused by the fact that in such situations FLUSH TABLES table_list WITH READ LOCK implementation tried to use (e.g. lock) such child tables without acquiring metadata lock on them. This happened because when opening tables we assumed metadata locks on all tables were already acquired earlier during statement execution and a such assumption was false for MERGE children. This patch fixes the problem by ensuring at open_tables() time that we try to acquire metadata locks on all tables to be opened. For normal tables such requests are satisfied instantly since locks are already acquired for them. For MERGE children metadata locks are acquired in normal fashion. Note that FLUSH TABLES merge_table WITH READ LOCK will lock for read both the MERGE table and its children but will flush only the MERGE table. To flush children one has to mention them in table list explicitly. This is expected behavior and it is consistent with usage patterns for this statement (e.g. in mysqlhotcopy script).
This commit is contained in:
@ -373,3 +373,53 @@ commit;
|
||||
# --> connection con2
|
||||
# --> connection default
|
||||
drop table t1;
|
||||
#
|
||||
# Test for bug #55273 "FLUSH TABLE tm WITH READ LOCK for Merge table
|
||||
# causes assert failure".
|
||||
#
|
||||
drop table if exists t1, t2, tm;
|
||||
create table t1 (i int);
|
||||
create table t2 (i int);
|
||||
create table tm (i int) engine=merge union=(t1, t2);
|
||||
insert into t1 values (1), (2);
|
||||
insert into t2 values (3), (4);
|
||||
# The below statement should succeed and lock merge
|
||||
# table for read. Only merge table gets flushed and
|
||||
# not underlying tables.
|
||||
flush tables tm with read lock;
|
||||
select * from tm;
|
||||
i
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
# Check that underlying tables are locked.
|
||||
select * from t1;
|
||||
i
|
||||
1
|
||||
2
|
||||
select * from t2;
|
||||
i
|
||||
3
|
||||
4
|
||||
unlock tables;
|
||||
# This statement should succeed as well and flush
|
||||
# all tables in the list.
|
||||
flush tables tm, t1, t2 with read lock;
|
||||
select * from tm;
|
||||
i
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
# Naturally, underlying tables should be locked in this case too.
|
||||
select * from t1;
|
||||
i
|
||||
1
|
||||
2
|
||||
select * from t2;
|
||||
i
|
||||
3
|
||||
4
|
||||
unlock tables;
|
||||
drop tables tm, t1, t2;
|
||||
|
Reference in New Issue
Block a user