I can repeat with the following test, on both mariadb-10.3.14 and the latest 10.3 development version (ef44ec4afaa):
--source include/have_innodb.inc
|
--source include/have_sequence.inc
|
--source include/count_sessions.inc
|
|
let $ID= `SELECT @id := CONNECTION_ID()`;
|
|
connect (con1, localhost, root,,);
|
let $ignore= `SELECT @id := $ID`;
|
|
connection default;
|
send CREATE TABLE t1 ENGINE=InnoDB SELECT * FROM seq_1_to_100000000;
|
|
connection con1;
|
let $wait_condition=
|
select count(*) = 1 from information_schema.processlist
|
where state = 'Sending data'
|
and info = 'CREATE TABLE t1 ENGINE=InnoDB SELECT * FROM seq_1_to_100000000';
|
--source include/wait_condition.inc
|
KILL QUERY @id;
|
disconnect con1;
|
|
connection default;
|
--error ER_QUERY_INTERRUPTED
|
reap;
|
|
CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB;
|
DROP TABLE t1;
|
--source include/wait_until_count_sessions.inc
|
The CREATE TABLE…SELECT is internally implemented as two transactions, performing CREATE TABLE and INSERT…SELECT. If the operation is interrupted at the CREATE TABLE phase, then it will be rolled back properly. If it is interrupted during the INSERT…SELECT, then apparently the .frm file will be deleted, but the table will not be dropped inside InnoDB. We appear to be missing error handling (DROP TABLE) if the operation was interrupted. Such handling does exists for some errors.
In MariaDB 5.5, there is no SEQUENCE engine, so I tried a different test:
--source include/have_innodb.inc
|
--source include/count_sessions.inc
|
|
let $ID= `SELECT @id := CONNECTION_ID()`;
|
|
CREATE TEMPORARY TABLE t (a INT);
|
INSERT INTO t VALUES(1),(2),(3);
|
|
connect (con1, localhost, root,,);
|
let $ignore= `SELECT @id := $ID`;
|
|
connection default;
|
send CREATE TABLE t1 ENGINE=InnoDB SELECT a,SLEEP(1) FROM t;
|
|
connection con1;
|
let $wait_condition=
|
select count(*) = 1 from information_schema.processlist
|
where state != 'Creating table'
|
and info = 'CREATE TABLE t1 ENGINE=InnoDB SELECT a,SLEEP(1) FROM t';
|
--source include/wait_condition.inc
|
KILL QUERY @id;
|
disconnect con1;
|
|
connection default;
|
--error ER_QUERY_INTERRUPTED
|
reap;
|
|
CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB;
|
DROP TABLE t1;
|
--source include/wait_until_count_sessions.inc
|
It looks like when the execution is interrupted while executing the SLEEP function, the table will be dropped correctly (in both 10.3 and 5.5, which I tested). Here is the call stack for dropping the table in 5.5:
5.5 f90040fd9ccb99cb4541d181a7052c37dc38decb
|
#0 ha_innobase::delete_table (this=0x7fffc4015b18,
|
name=0x7ffff43abac0 "./test/t1")
|
at /mariadb/5.5/storage/xtradb/handler/ha_innodb.cc:8746
|
#1 0x0000555555af12de in handler::ha_delete_table (this=0x7fffc4015b18,
|
name=0x7ffff43abac0 "./test/t1") at /mariadb/5.5/sql/handler.cc:3724
|
#2 0x0000555555aee3eb in ha_delete_table (thd=0x555557c07090,
|
table_type=0x555556fe7e30, path=0x7ffff43abac0 "./test/t1",
|
db=0x7fffc40077f8 "test", alias=0x7fffc40071e8 "t1",
|
generate_warning=false) at /mariadb/5.5/sql/handler.cc:2156
|
#3 0x00005555559d0c67 in quick_rm_table (base=0x555556fe7e30,
|
db=0x7fffc40077f8 "test", table_name=0x7fffc40071e8 "t1", flags=0)
|
at /mariadb/5.5/sql/sql_table.cc:2491
|
#4 0x00005555558d9fb2 in drop_open_table (thd=0x555557c07090,
|
table=0x7fffc4017ad0, db_name=0x7fffc40077f8 "test",
|
table_name=0x7fffc40071e8 "t1") at /mariadb/5.5/sql/sql_base.cc:2410
|
#5 0x0000555555924a14 in select_create::abort_result_set (
|
this=0x7fffc40082d8) at /mariadb/5.5/sql/sql_insert.cc:4318
|
#6 0x0000555555966ea2 in handle_select (thd=0x555557c07090,
|
lex=0x555557c0a308, result=0x7fffc40082d8, setup_tables_done_option=0)
|
at /mariadb/5.5/sql/sql_select.cc:330
|
#7 0x0000555555939a3e in mysql_execute_command (thd=0x555557c07090)
|
at /mariadb/5.5/sql/sql_parse.cc:2610
|
#8 0x00005555559428bd in mysql_parse (thd=0x555557c07090,
|
rawbuf=0x7fffc4007108 "CREATE TABLE t1 ENGINE=InnoDB SELECT a,SLEEP(1) FROM t", length=54, parser_state=0x7ffff43ac650)
|
at /mariadb/5.5/sql/sql_parse.cc:5929
|
Workaround: To drop the table from the InnoDB data dictionary afterwards, you could copy the .frm file of a similar InnoDB table to the ‘phantom’ name, and then issue DROP TABLE.
I can repeat with the following test, on both mariadb-10.3.14 and the latest 10.3 development version (ef44ec4afaa):
--source include/have_innodb.inc
--source include/have_sequence.inc
--source include/count_sessions.inc
let $wait_condition=
--source include/wait_condition.inc
KILL QUERY @id;
disconnect con1;
--error ER_QUERY_INTERRUPTED
reap;
The CREATE TABLE…SELECT is internally implemented as two transactions, performing CREATE TABLE and INSERT…SELECT. If the operation is interrupted at the CREATE TABLE phase, then it will be rolled back properly. If it is interrupted during the INSERT…SELECT, then apparently the .frm file will be deleted, but the table will not be dropped inside InnoDB. We appear to be missing error handling (DROP TABLE) if the operation was interrupted. Such handling does exists for some errors.
In MariaDB 5.5, there is no SEQUENCE engine, so I tried a different test:
--source include/have_innodb.inc
--source include/count_sessions.inc
let $wait_condition=
--source include/wait_condition.inc
KILL QUERY @id;
disconnect con1;
--error ER_QUERY_INTERRUPTED
reap;
It looks like when the execution is interrupted while executing the SLEEP function, the table will be dropped correctly (in both 10.3 and 5.5, which I tested). Here is the call stack for dropping the table in 5.5:
5.5 f90040fd9ccb99cb4541d181a7052c37dc38decb
#0 ha_innobase::delete_table (this=0x7fffc4015b18,
name=0x7ffff43abac0 "./test/t1")
at /mariadb/5.5/storage/xtradb/handler/ha_innodb.cc:8746
#1 0x0000555555af12de in handler::ha_delete_table (this=0x7fffc4015b18,
name=0x7ffff43abac0 "./test/t1") at /mariadb/5.5/sql/handler.cc:3724
#2 0x0000555555aee3eb in ha_delete_table (thd=0x555557c07090,
table_type=0x555556fe7e30, path=0x7ffff43abac0 "./test/t1",
db=0x7fffc40077f8 "test", alias=0x7fffc40071e8 "t1",
generate_warning=false) at /mariadb/5.5/sql/handler.cc:2156
#3 0x00005555559d0c67 in quick_rm_table (base=0x555556fe7e30,
db=0x7fffc40077f8 "test", table_name=0x7fffc40071e8 "t1", flags=0)
at /mariadb/5.5/sql/sql_table.cc:2491
#4 0x00005555558d9fb2 in drop_open_table (thd=0x555557c07090,
table=0x7fffc4017ad0, db_name=0x7fffc40077f8 "test",
table_name=0x7fffc40071e8 "t1") at /mariadb/5.5/sql/sql_base.cc:2410
#5 0x0000555555924a14 in select_create::abort_result_set (
this=0x7fffc40082d8) at /mariadb/5.5/sql/sql_insert.cc:4318
#6 0x0000555555966ea2 in handle_select (thd=0x555557c07090,
lex=0x555557c0a308, result=0x7fffc40082d8, setup_tables_done_option=0)
at /mariadb/5.5/sql/sql_select.cc:330
#7 0x0000555555939a3e in mysql_execute_command (thd=0x555557c07090)
at /mariadb/5.5/sql/sql_parse.cc:2610
#8 0x00005555559428bd in mysql_parse (thd=0x555557c07090,
rawbuf=0x7fffc4007108 "CREATE TABLE t1 ENGINE=InnoDB SELECT a,SLEEP(1) FROM t", length=54, parser_state=0x7ffff43ac650)
at /mariadb/5.5/sql/sql_parse.cc:5929
Workaround: To drop the table from the InnoDB data dictionary afterwards, you could copy the .frm file of a similar InnoDB table to the ‘phantom’ name, and then issue DROP TABLE.