Commit 6211c355 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-23391 Crash/assertion CREATE OR REPLACE TABLE AS SELECT under LOCK TABLE

Happens with Innodb engine.

Move unlock_locked_table() past drop_open_table(), and
rollback current statement, so that we can actually unlock the table.

Anything else results in assertions, in drop, or unlock, or in close_table.
parent 81b85476
......@@ -313,6 +313,25 @@ create table t1 (i int);
drop table t1;
drop database mysqltest2;
#
# MDEV-23391 Server crash in close_thread_table or assertion, upon CREATE OR REPLACE TABLE under lock
#
create table t1 (i int);
lock table t1 write;
select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
# MDL_INTENTION_EXCLUSIVE NULL Global read lock
# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test
# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1
create or replace table t1 (a char(1)) engine=Innodb select 'foo' as a;
ERROR 22001: Data too long for column 'a' at row 1
show tables;
Tables_in_test
t2
select * from information_schema.metadata_lock_info;
THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
create table t1 (i int);
drop table t1;
#
# Testing CREATE .. LIKE
#
create or replace table t1 like t2;
......
......@@ -251,6 +251,25 @@ create table t1 (i int);
drop table t1;
drop database mysqltest2;
--echo #
--echo # MDEV-23391 Server crash in close_thread_table or assertion, upon CREATE OR REPLACE TABLE under lock
--echo #
create table t1 (i int);
lock table t1 write;
--replace_column 1 #
--sorted_result
select * from information_schema.metadata_lock_info;
--error ER_DATA_TOO_LONG
create or replace table t1 (a char(1)) engine=Innodb select 'foo' as a;
show tables;
--replace_column 1 #
--sorted_result
select * from information_schema.metadata_lock_info;
create table t1 (i int);
drop table t1;
--echo #
--echo # Testing CREATE .. LIKE
--echo #
......
......@@ -4708,12 +4708,6 @@ void select_create::abort_result_set()
/* possible error of writing binary log is ignored deliberately */
(void) thd->binlog_flush_pending_rows_event(TRUE, TRUE);
if (create_info->table_was_deleted)
{
/* Unlock locked table that was dropped by CREATE */
thd->locked_tables_list.unlock_locked_table(thd,
create_info->mdl_ticket);
}
if (table)
{
bool tmp_table= table->s->tmp_table;
......@@ -4751,5 +4745,13 @@ void select_create::abort_result_set()
tmp_table);
}
}
if (create_info->table_was_deleted)
{
/* Unlock locked table that was dropped by CREATE. */
(void) trans_rollback_stmt(thd);
thd->locked_tables_list.unlock_locked_table(thd, create_info->mdl_ticket);
}
DBUG_VOID_RETURN;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment