summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/drop.result13
-rw-r--r--mysql-test/t/drop.test41
-rw-r--r--sql/lock.cc7
3 files changed, 59 insertions, 2 deletions
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index 979e5d48871..d122dabc4ec 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -72,3 +72,16 @@ show tables;
Tables_in_test
t1
drop table t1;
+drop database if exists mysqltest;
+drop table if exists t1;
+create table t1 (i int);
+lock tables t1 read;
+create database mysqltest;
+ drop table t1;
+show open tables;
+ drop database mysqltest;
+select 1;
+1
+1
+unlock tables;
+End of 5.0 tests
diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test
index 7cd943d46da..a1451773e90 100644
--- a/mysql-test/t/drop.test
+++ b/mysql-test/t/drop.test
@@ -81,3 +81,44 @@ show tables;
drop table t1;
# End of 4.1 tests
+
+
+#
+# Test for bug#21216 "Simultaneous DROP TABLE and SHOW OPEN TABLES causes
+# server to crash". Crash (caused by failed assertion in 5.0 or by null
+# pointer dereference in 5.1) happened when one ran SHOW OPEN TABLES
+# while concurrently doing DROP TABLE (or RENAME TABLE, CREATE TABLE LIKE
+# or any other command that takes name-lock) in other connection.
+#
+# Also includes test for similar bug#12212 "Crash that happens during
+# removing of database name from cache" reappeared in 5.1 as bug#19403
+# In its case crash happened when one concurrently executed DROP DATABASE
+# and one of name-locking command.
+#
+--disable_warnings
+drop database if exists mysqltest;
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int);
+lock tables t1 read;
+create database mysqltest;
+connect (addconroot1, localhost, root,,);
+--send drop table t1
+connect (addconroot2, localhost, root,,);
+# Server should not crash in any of the following statements
+--disable_result_log
+show open tables;
+--enable_result_log
+--send drop database mysqltest
+connection default;
+select 1;
+unlock tables;
+connection addconroot1;
+--reap
+connection addconroot2;
+--reap
+disconnect addconroot1;
+disconnect addconroot2;
+connection default;
+
+--echo End of 5.0 tests
diff --git a/sql/lock.cc b/sql/lock.cc
index 97a080c5634..90ddcc957a2 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -854,6 +854,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
TABLE *table;
char key[MAX_DBKEY_LENGTH];
char *db= table_list->db;
+ int table_in_key_offset;
uint key_length;
HASH_SEARCH_STATE state;
DBUG_ENTER("lock_table_name");
@@ -861,8 +862,9 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
safe_mutex_assert_owner(&LOCK_open);
- key_length=(uint) (strmov(strmov(key,db)+1,table_list->table_name)
- -key)+ 1;
+ table_in_key_offset= strmov(key, db) - key + 1;
+ key_length= (uint)(strmov(key + table_in_key_offset, table_list->table_name)
+ - key) + 1;
/* Only insert the table if we haven't insert it already */
@@ -883,6 +885,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
table->s= &table->share_not_to_be_used;
memcpy((table->s->table_cache_key= (char*) (table+1)), key, key_length);
table->s->db= table->s->table_cache_key;
+ table->s->table_name= table->s->table_cache_key + table_in_key_offset;
table->s->key_length=key_length;
table->in_use=thd;
table->locked_by_name=1;