From eea07f5f5845c2fa5009546f6c1ed703f17a60b9 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sun, 22 Oct 2017 20:14:52 +0300 Subject: [PATCH] MDEV-13721 Assertion is_lock_owner() failed in mysql_rm_table_no_locks This happened when trying to do delete a sequence hidden by a temporary table. Fixed by ignoring non-sequence temporary tables when trying to drop sequences. Signed-off-by: Monty --- mysql-test/suite/sql_sequence/create.result | 62 +++++++++++++++++++++ mysql-test/suite/sql_sequence/create.test | 30 ++++++++++ sql/sql_table.cc | 21 ++++++- 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result index 6a45ec09444..0a44dfe8931 100644 --- a/mysql-test/suite/sql_sequence/create.result +++ b/mysql-test/suite/sql_sequence/create.result @@ -571,3 +571,65 @@ ERROR 42S02: 'test.s' is not a SEQUENCE show create sequence s2; ERROR 42S02: 'test.s2' is not a SEQUENCE drop table s,s2; +# +# MDEV-13721 Assertion is_lock_owner() failed in mysql_rm_table_no_locks +# +create or replace sequence s; +create temporary table s (i int); +drop sequence s; +show create table s; +Table Create Table +s CREATE TEMPORARY TABLE `s` ( + `i` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table s; +create or replace sequence s; +create temporary sequence s; +show create table s; +Table Create Table +s CREATE TEMPORARY TABLE `s` ( + `next_not_cached_value` bigint(21) NOT NULL, + `minimum_value` bigint(21) NOT NULL, + `maximum_value` bigint(21) NOT NULL, + `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used', + `increment` bigint(21) NOT NULL COMMENT 'increment value', + `cache_size` bigint(21) unsigned NOT NULL, + `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed', + `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done' +) ENGINE=MyISAM SEQUENCE=1 +drop sequence s; +show create table s; +Table Create Table +s CREATE TABLE `s` ( + `next_not_cached_value` bigint(21) NOT NULL, + `minimum_value` bigint(21) NOT NULL, + `maximum_value` bigint(21) NOT NULL, + `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used', + `increment` bigint(21) NOT NULL COMMENT 'increment value', + `cache_size` bigint(21) unsigned NOT NULL, + `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed', + `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done' +) ENGINE=MyISAM SEQUENCE=1 +drop table s; +create or replace sequence s; +create temporary sequence s; +drop temporary sequence s; +show create table s; +Table Create Table +s CREATE TABLE `s` ( + `next_not_cached_value` bigint(21) NOT NULL, + `minimum_value` bigint(21) NOT NULL, + `maximum_value` bigint(21) NOT NULL, + `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used', + `increment` bigint(21) NOT NULL COMMENT 'increment value', + `cache_size` bigint(21) unsigned NOT NULL, + `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed', + `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done' +) ENGINE=MyISAM SEQUENCE=1 +drop table s; +create temporary sequence s; +drop temporary table s; +create temporary table s (i int); +drop temporary sequence s; +ERROR 42S02: Unknown SEQUENCE: 'test.s' +drop table s; diff --git a/mysql-test/suite/sql_sequence/create.test b/mysql-test/suite/sql_sequence/create.test index ded34113d09..6696e78db92 100644 --- a/mysql-test/suite/sql_sequence/create.test +++ b/mysql-test/suite/sql_sequence/create.test @@ -419,3 +419,33 @@ show create sequence s; --error ER_NOT_SEQUENCE show create sequence s2; drop table s,s2; + +--echo # +--echo # MDEV-13721 Assertion is_lock_owner() failed in mysql_rm_table_no_locks +--echo # + +create or replace sequence s; +create temporary table s (i int); +drop sequence s; +show create table s; +drop table s; + +create or replace sequence s; +create temporary sequence s; +show create table s; +drop sequence s; +show create table s; +drop table s; + +create or replace sequence s; +create temporary sequence s; +drop temporary sequence s; +show create table s; +drop table s; + +create temporary sequence s; +drop temporary table s; +create temporary table s (i int); +--error ER_UNKNOWN_SEQUENCES +drop temporary sequence s; +drop table s; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dd7baa31a12..c85a8be85ab 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1990,7 +1990,7 @@ int write_bin_log(THD *thd, bool clear_error, tables List of tables to delete if_exists If 1, don't give error if one table doesn't exists drop_temporary 1 if DROP TEMPORARY - drop_seqeunce 1 if DROP SEQUENCE + drop_sequence 1 if DROP SEQUENCE NOTES Will delete all tables that can be deleted and give a compact error @@ -2038,6 +2038,25 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists, if (!thd->locked_tables_mode) { + if (drop_sequence) + { + /* We are trying to drop a sequence. + Change all temporary tables that are not sequences to + normal tables so that we can try to drop them instead. + If we don't do this, we will get an error 'not a sequence' + when trying to drop a sequence that is hidden by a temporary + table. + */ + for (table= tables; table; table= table->next_global) + { + if (table->open_type == OT_TEMPORARY_OR_BASE && + is_temporary_table(table) && !table->table->s->sequence) + { + thd->mark_tmp_table_as_free_for_reuse(table->table); + table->table= NULL; + } + } + } if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout, 0)) DBUG_RETURN(true);