1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-30364 Assertion MDL_EXCLUSIVE on DISCARD TABLESPACE in LOCK TABLE mode

In locked_tables_mode when table is opened without
MYSQL_OPEN_GET_NEW_TABLE flag it is taken from pre-opened and locked
tables. In that case we upgrade its MDL ticket to MDL_EXCLUSIVE before
the operation and downgrade after operation.
This commit is contained in:
Aleksey Midenkov
2025-07-08 14:01:50 +03:00
committed by Sergei Golubchik
parent db3e1edac3
commit aedc65fe10
3 changed files with 87 additions and 1 deletions

View File

@@ -320,3 +320,30 @@ SHOW VARIABLES LIKE 'DEBUG_SYNC';
Variable_name Value Variable_name Value
debug_sync ON - current signals: 's2,s7,s1,s5' debug_sync ON - current signals: 's2,s7,s1,s5'
SET DEBUG_SYNC= 'RESET'; SET DEBUG_SYNC= 'RESET';
#
# MDEV-30364 Assertion MDL_EXCLUSIVE on DISCARD TABLESPACE in LOCK TABLE mode
#
create table t (c int) engine=innodb;
connect con1,localhost,root;
set debug_sync='get_schema_column WAIT_FOR go';
select column_name from information_schema.columns
where table_schema='test' and table_name='t';
connection default;
lock table t write;
alter table t discard tablespace;
connect con2,localhost,root;
disconnect con2;
connection default;
ERROR 70100: Query execution was interrupted
set debug_sync='now SIGNAL go';
connection con1;
column_name
c
disconnect con1;
connection default;
unlock tables;
drop table t;
set debug_sync= 'reset';
#
# End of 10.6 tests
#

View File

@@ -18,6 +18,7 @@
# We need the Debug Sync Facility. # We need the Debug Sync Facility.
# #
--source include/have_debug_sync.inc --source include/have_debug_sync.inc
--source include/have_innodb.inc
# #
# We are checking privileges, which the embedded server cannot do. # We are checking privileges, which the embedded server cannot do.
@@ -448,3 +449,42 @@ SHOW VARIABLES LIKE 'DEBUG_SYNC';
# #
SET DEBUG_SYNC= 'RESET'; SET DEBUG_SYNC= 'RESET';
--echo #
--echo # MDEV-30364 Assertion MDL_EXCLUSIVE on DISCARD TABLESPACE in LOCK TABLE mode
--echo #
create table t (c int) engine=innodb;
--connect con1,localhost,root
set debug_sync='get_schema_column WAIT_FOR go';
send select column_name from information_schema.columns
where table_schema='test' and table_name='t';
--connection default
let $wait_condition=select 1 from information_schema.processlist where state like 'debug sync point%';
--source include/wait_condition.inc
let $connid=`select connection_id()`;
lock table t write;
send alter table t discard tablespace;
--connect con2,localhost,root
--disable_query_log
--eval kill query $connid
--enable_query_log
--disconnect con2
--connection default
--error ER_QUERY_INTERRUPTED
reap;
set debug_sync='now SIGNAL go';
--connection con1
reap;
--disconnect con1
--connection default
unlock tables;
drop table t;
set debug_sync= 'reset';
--echo #
--echo # End of 10.6 tests
--echo #

View File

@@ -5946,6 +5946,8 @@ int mysql_discard_or_import_tablespace(THD *thd,
{ {
Alter_table_prelocking_strategy alter_prelocking_strategy; Alter_table_prelocking_strategy alter_prelocking_strategy;
int error; int error;
TABLE *table;
enum_mdl_type mdl_downgrade= MDL_NOT_INITIALIZED;
DBUG_ENTER("mysql_discard_or_import_tablespace"); DBUG_ENTER("mysql_discard_or_import_tablespace");
mysql_audit_alter_table(thd, table_list); mysql_audit_alter_table(thd, table_list);
@@ -5978,7 +5980,21 @@ int mysql_discard_or_import_tablespace(THD *thd,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
error= table_list->table->file->ha_discard_or_import_tablespace(discard); table= table_list->table;
DBUG_ASSERT(table->mdl_ticket || table->s->tmp_table);
if (table->mdl_ticket && table->mdl_ticket->get_type() < MDL_EXCLUSIVE)
{
DBUG_ASSERT(thd->locked_tables_mode);
mdl_downgrade= table->mdl_ticket->get_type();
if (thd->mdl_context.upgrade_shared_lock(table->mdl_ticket, MDL_EXCLUSIVE,
thd->variables.lock_wait_timeout))
{
error= 1;
goto err;
}
}
error= table->file->ha_discard_or_import_tablespace(discard);
THD_STAGE_INFO(thd, stage_end); THD_STAGE_INFO(thd, stage_end);
@@ -6004,6 +6020,9 @@ int mysql_discard_or_import_tablespace(THD *thd,
err: err:
thd->tablespace_op=FALSE; thd->tablespace_op=FALSE;
if (mdl_downgrade > MDL_NOT_INITIALIZED)
table->mdl_ticket->downgrade_lock(mdl_downgrade);
if (likely(error == 0)) if (likely(error == 0))
{ {
my_ok(thd); my_ok(thd);