summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2020-03-22 11:33:53 +0100
committerOleksandr Byelkin <sanja@mariadb.com>2020-12-09 12:31:12 +0100
commit86fc37b66877e45c38593e7af15159c32f81eb7c (patch)
tree3b4a9650f7324c5cde3792ae89ea1d0c62367ecf
parentbc2dc83cb56851144a8c15e73a83c7817dc705a2 (diff)
downloadmariadb-git-bb-10.3-MDEV-19273.tar.gz
MDEV-19273: Server crash in MDL_ticket::has_stronger_or_equal_type or Assertion `thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db.str, table->table_name.str, MDL_SHARED)' failed in mysql_rm_table_no_locksbb-10.3-MDEV-19273
Early report error in case of DROP SEQUENCE <non-sequence> Do not use error variable for other purposes except error.
-rw-r--r--mysql-test/suite/sql_sequence/create.result2
-rw-r--r--mysql-test/suite/sql_sequence/create.test2
-rw-r--r--mysql-test/suite/sql_sequence/other.result59
-rw-r--r--mysql-test/suite/sql_sequence/other.test64
-rw-r--r--sql/sql_table.cc56
5 files changed, 169 insertions, 14 deletions
diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result
index 14464c60e99..5a53a66c9a8 100644
--- a/mysql-test/suite/sql_sequence/create.result
+++ b/mysql-test/suite/sql_sequence/create.result
@@ -666,7 +666,7 @@ create temporary sequence s;
drop temporary table s;
create temporary table s (i int);
drop temporary sequence s;
-ERROR 42S02: Unknown SEQUENCE: 'test.s'
+ERROR 42S02: 'test.s' is not a SEQUENCE
drop table s;
#
# MDEV-15115 Assertion failure in CREATE SEQUENCE...ROW_FORMAT=REDUNDANT
diff --git a/mysql-test/suite/sql_sequence/create.test b/mysql-test/suite/sql_sequence/create.test
index 2c41fb3658b..ac3aae845cd 100644
--- a/mysql-test/suite/sql_sequence/create.test
+++ b/mysql-test/suite/sql_sequence/create.test
@@ -489,7 +489,7 @@ drop table s;
create temporary sequence s;
drop temporary table s;
create temporary table s (i int);
---error ER_UNKNOWN_SEQUENCES
+--error ER_NOT_SEQUENCE2
drop temporary sequence s;
drop table s;
diff --git a/mysql-test/suite/sql_sequence/other.result b/mysql-test/suite/sql_sequence/other.result
index abc101b3c00..643233149d2 100644
--- a/mysql-test/suite/sql_sequence/other.result
+++ b/mysql-test/suite/sql_sequence/other.result
@@ -300,4 +300,63 @@ update t1 set p_first_name='Yunxi' where p_id=1;
drop view v2;
drop table t1,t2;
drop sequence s1;
+#
+# MDEV-19273:Server crash in MDL_ticket::has_stronger_or_equal_type or
+# Assertion `thd->mdl_context.is_lock_owner(MDL_key::TABLE,
+# table->db.str, table->table_name.str, MDL_SHARED)' failed
+# in mysql_rm_table_no_locks
+#
+CREATE TABLE t1 (a INT);
+CREATE TEMPORARY TABLE tmp (b INT);
+LOCK TABLE t1 READ;
+DROP SEQUENCE tmp;
+ERROR 42S02: 'test.tmp' is not a SEQUENCE
+DROP TEMPORARY SEQUENCE tmp;
+ERROR 42S02: 'test.tmp' is not a SEQUENCE
+DROP SEQUENCE t1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+DROP TEMPORARY SEQUENCE t1;
+ERROR 42S02: Unknown SEQUENCE: 'test.t1'
+UNLOCK TABLES;
+DROP SEQUENCE t1;
+ERROR 42S02: 'test.t1' is not a SEQUENCE
+DROP TEMPORARY SEQUENCE t1;
+ERROR 42S02: Unknown SEQUENCE: 'test.t1'
+DROP TABLE t1;
+CREATE TABLE t (a INT);
+CREATE TEMPORARY TABLE s (f INT);
+CREATE SEQUENCE s;
+LOCK TABLE t WRITE;
+DROP SEQUENCE s;
+ERROR 42S02: 'test.s' is not a SEQUENCE
+DROP TEMPORARY SEQUENCE s;
+ERROR 42S02: 'test.s' is not a SEQUENCE
+UNLOCK TABLES;
+CREATE TEMPORARY SEQUENCE s;
+LOCK TABLE t WRITE;
+DROP TEMPORARY SEQUENCE s;
+UNLOCK TABLES;
+DROP TEMPORARY TABLE s;
+DROP SEQUENCE s;
+create table s(a INT);
+CREATE TEMPORARY TABLE s (f INT);
+LOCK TABLE t WRITE;
+DROP TEMPORARY TABLE s;
+CREATE TEMPORARY TABLE s (f INT);
+DROP TABLE s;
+DROP TABLE s;
+ERROR HY000: Table 's' was not locked with LOCK TABLES
+UNLOCK TABLES;
+DROP TABLE s;
+CREATE VIEW v1 as SELECT * FROM t;
+CREATE SEQUENCE s;
+DROP SEQUENCE IF EXISTS v1;
+Warnings:
+Note 4091 Unknown SEQUENCE: 'test.v1'
+DROP VIEW IF EXISTS s;
+Warnings:
+Note 4092 Unknown VIEW: 'test.s'
+DROP VIEW v1;
+DROP SEQUENCE s;
+DROP TABLE t;
# End of 10.3 tests
diff --git a/mysql-test/suite/sql_sequence/other.test b/mysql-test/suite/sql_sequence/other.test
index 70c4efa40e5..0fbb2d0e2f9 100644
--- a/mysql-test/suite/sql_sequence/other.test
+++ b/mysql-test/suite/sql_sequence/other.test
@@ -315,4 +315,68 @@ drop view v2;
drop table t1,t2;
drop sequence s1;
+--echo #
+--echo # MDEV-19273:Server crash in MDL_ticket::has_stronger_or_equal_type or
+--echo # Assertion `thd->mdl_context.is_lock_owner(MDL_key::TABLE,
+--echo # table->db.str, table->table_name.str, MDL_SHARED)' failed
+--echo # in mysql_rm_table_no_locks
+--echo #
+
+CREATE TABLE t1 (a INT);
+CREATE TEMPORARY TABLE tmp (b INT);
+LOCK TABLE t1 READ;
+--error ER_NOT_SEQUENCE2
+DROP SEQUENCE tmp;
+--error ER_NOT_SEQUENCE2
+DROP TEMPORARY SEQUENCE tmp;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+DROP SEQUENCE t1;
+--error ER_UNKNOWN_SEQUENCES
+DROP TEMPORARY SEQUENCE t1;
+UNLOCK TABLES;
+--error ER_NOT_SEQUENCE2
+DROP SEQUENCE t1;
+--error ER_UNKNOWN_SEQUENCES
+DROP TEMPORARY SEQUENCE t1;
+
+# Cleanup
+DROP TABLE t1;
+
+
+CREATE TABLE t (a INT);
+CREATE TEMPORARY TABLE s (f INT);
+CREATE SEQUENCE s;
+LOCK TABLE t WRITE;
+--error ER_NOT_SEQUENCE2
+DROP SEQUENCE s;
+--error ER_NOT_SEQUENCE2
+DROP TEMPORARY SEQUENCE s;
+UNLOCK TABLES;
+CREATE TEMPORARY SEQUENCE s;
+LOCK TABLE t WRITE;
+DROP TEMPORARY SEQUENCE s;
+UNLOCK TABLES;
+DROP TEMPORARY TABLE s;
+DROP SEQUENCE s;
+
+create table s(a INT);
+CREATE TEMPORARY TABLE s (f INT);
+LOCK TABLE t WRITE;
+DROP TEMPORARY TABLE s;
+CREATE TEMPORARY TABLE s (f INT);
+DROP TABLE s;
+--error ER_TABLE_NOT_LOCKED
+DROP TABLE s;
+UNLOCK TABLES;
+DROP TABLE s;
+
+CREATE VIEW v1 as SELECT * FROM t;
+CREATE SEQUENCE s;
+
+DROP SEQUENCE IF EXISTS v1;
+DROP VIEW IF EXISTS s;
+
+DROP VIEW v1;
+DROP SEQUENCE s;
+DROP TABLE t;
--echo # End of 10.3 tests
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 96d270b25ff..55cc33b4680 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2314,8 +2314,11 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
{
bool is_trans= 0;
bool table_creation_was_logged= 0;
+ bool real_table= FALSE;
LEX_CSTRING db= table->db;
handlerton *table_type= 0;
+ // reset error state for this table
+ error= 0;
DBUG_PRINT("table", ("table_l: '%s'.'%s' table: %p s: %p",
table->db.str, table->table_name.str, table->table,
@@ -2331,9 +2334,35 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
thd->find_temporary_table(table) &&
table->mdl_request.ticket != NULL));
- if (table->open_type == OT_BASE_ONLY || !is_temporary_table(table) ||
- (drop_sequence && table->table->s->table_type != TABLE_TYPE_SEQUENCE))
+ if (table->open_type == OT_BASE_ONLY || !is_temporary_table(table))
+ real_table= TRUE;
+ else if (drop_sequence &&
+ table->table->s->table_type != TABLE_TYPE_SEQUENCE)
+ {
+ was_table= (table->table->s->table_type == TABLE_TYPE_NORMAL);
+ was_view= (table->table->s->table_type == TABLE_TYPE_VIEW);
+ if (if_exists)
+ {
+ char buff[FN_REFLEN];
+ String tbl_name(buff, sizeof(buff), system_charset_info);
+ tbl_name.length(0);
+ tbl_name.append(&db);
+ tbl_name.append('.');
+ tbl_name.append(&table->table_name);
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_NOT_SEQUENCE2, ER_THD(thd, ER_NOT_SEQUENCE2),
+ tbl_name.c_ptr_safe());
+
+ /*
+ Our job is done here. This statement was added to avoid executing
+ unnecessary code farther below which in some strange corner cases
+ caused the server to crash (see MDEV-17896).
+ */
+ goto log_query;
+ }
error= 1;
+ goto non_critical_err;
+ }
else
{
table_creation_was_logged= table->table->s->table_creation_was_logged;
@@ -2342,29 +2371,28 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
error= 1;
goto err;
}
- error= 0;
table->table= 0;
}
- if ((drop_temporary && if_exists) || !error)
+ if ((drop_temporary && if_exists) || !real_table)
{
/*
This handles the case of temporary tables. We have the following cases:
. "DROP TEMPORARY" was executed and a temporary table was affected
- (i.e. drop_temporary && !error) or the if_exists was specified (i.e.
- drop_temporary && if_exists).
+ (i.e. drop_temporary && !real_table) or the
+ if_exists was specified (i.e. drop_temporary && if_exists).
. "DROP" was executed but a temporary table was affected (.i.e
- !error).
+ !real_table).
*/
if (!dont_log_query && table_creation_was_logged)
{
/*
- If there is an error, we don't know the type of the engine
+ If there is an real_table, we don't know the type of the engine
at this point. So, we keep it in the trx-cache.
*/
- is_trans= error ? TRUE : is_trans;
+ is_trans= real_table ? TRUE : is_trans;
if (is_trans)
trans_tmp_table_deleted= TRUE;
else
@@ -2391,7 +2419,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
is no need to proceed with the code that tries to drop a regular
table.
*/
- if (!error) continue;
+ if (!real_table) continue;
}
else if (!drop_temporary)
{
@@ -2407,7 +2435,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
reg_ext, 0);
}
DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
- error= 0;
if (drop_temporary ||
(ha_table_exists(thd, &db, &alias, &table_type, &is_sequence) == 0 &&
table_type == 0) ||
@@ -2447,6 +2474,11 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
{
non_tmp_error = (drop_temporary ? non_tmp_error : TRUE);
error= 1;
+ /*
+ non critical error (only for this table), so we continue.
+ Next we write it to wrong_tables and continue this loop
+ The same as "goto non_critical_err".
+ */
}
}
else
@@ -2540,7 +2572,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
}
non_tmp_error|= MY_TEST(error);
}
-
+non_critical_err:
if (error)
{
if (wrong_tables.length())