diff options
author | Robert Bindar <robert@mariadb.org> | 2019-10-10 12:58:29 +0300 |
---|---|---|
committer | Robert Bindar <robert@mariadb.org> | 2019-11-01 11:10:04 +0200 |
commit | 6f86150ab3c9059a9379fcc68cb90da78e59e5cb (patch) | |
tree | 1235fd6c6dd9c00f48a3dc3baac465a8eae1d361 | |
parent | d925aec1c10cebf6c34825a7de50afe4e630aff4 (diff) | |
download | mariadb-git-6f86150ab3c9059a9379fcc68cb90da78e59e5cb.tar.gz |
MDEV-17896 Assertion `pfs->get_refcount() > 0' failed
Unfortunate DROP TEMPORARY..IF EXISTS on a regular table may allow
subsequent CREATE TABLE statements to steal away the PFS_table_share
instance from the dropped table.
-rw-r--r-- | mysql-test/suite/perfschema/r/misc.result | 16 | ||||
-rw-r--r-- | mysql-test/suite/perfschema/t/misc.test | 48 | ||||
-rw-r--r-- | sql/sql_table.cc | 7 |
3 files changed, 71 insertions, 0 deletions
diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result index 7a097a27576..e2b7f6fab73 100644 --- a/mysql-test/suite/perfschema/r/misc.result +++ b/mysql-test/suite/perfschema/r/misc.result @@ -134,3 +134,19 @@ truncate performance_schema.events_statements_history 0 select * from t1 3 insert into t1 select RAND()*10000 from t1 6 drop table t1; +# +# MDEV-17896 Assertion `pfs->get_refcount() > 0' failed +# in release_table_share +# +SELECT COUNT(*)<@@performance_schema_max_table_instances FROM +performance_schema.objects_summary_global_by_type WHERE OBJECT_TYPE='TABLE'; +COUNT(*)<@@performance_schema_max_table_instances +1 +CREATE TABLE t0(a INT); +SELECT * FROM t0; +a +DROP TEMPORARY TABLE IF EXISTS t0; +Warnings: +Note 1051 Unknown table 'test.t0' +FLUSH TABLE t0; +DROP TABLE t0; diff --git a/mysql-test/suite/perfschema/t/misc.test b/mysql-test/suite/perfschema/t/misc.test index c9f7dc6bfc0..80ce64f0302 100644 --- a/mysql-test/suite/perfschema/t/misc.test +++ b/mysql-test/suite/perfschema/t/misc.test @@ -222,3 +222,51 @@ insert into t1 select RAND()*10000 from t1; select sql_text, rows_examined from performance_schema.events_statements_history; drop table t1; +--echo # +--echo # MDEV-17896 Assertion `pfs->get_refcount() > 0' failed +--echo # in release_table_share +--echo # + +# There must be at least one available slot in PFS table_share_array for +# this test to be meaningful. If there are no free slots we must +# restart mysqld, it is the only way to reset PFS table_share_array +let $query= SELECT COUNT(*)<@@performance_schema_max_table_instances FROM + performance_schema.objects_summary_global_by_type WHERE OBJECT_TYPE='TABLE'; + +let $free_slots_available= `$query`; + +if (!$free_slots_available) +{ + source include/restart_mysqld.inc; +} +eval $query; + +CREATE TABLE t0(a INT); + +# TABLE_SHARE must be cached in the table definition cache. +SELECT * FROM t0; + +# Dropping t0 using DROP TEMPORARY frees up a slot in table_share_array, +# but the persistent table is not correctly dropped, i.e. TABLE_SHARE::m_psi +# still points to that slot in table_share_array. +DROP TEMPORARY TABLE IF EXISTS t0; + +# Try re-using each and every slot in PFS table_share_array. If bug is +# there, we re-use t0 slot. +# The newly created table that re-uses the t0 slot ends up +# resetting the PFS_table_share refcount. +let $i= `SELECT @@performance_schema_max_table_instances`; +disable_query_log; +while ($i) +{ + # Memory engine is here to reduce disk IO + eval CREATE TABLE t$i(a INT) ENGINE=MEMORY; + eval DROP TABLE t$i; + dec $i; +} +enable_query_log; + +# FLUSH TABLE crashes the server when PFS_table_share is found with +# an unexpected refcount. +FLUSH TABLE t0; +DROP TABLE t0; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 467e91ce6c7..e694c52e272 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2418,6 +2418,13 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, ER_BAD_TABLE_ERROR, ER_THD(thd, ER_BAD_TABLE_ERROR), 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). + */ + continue; } else { |