Commit af96cbe1 authored by unknown's avatar unknown

row0mysql.c, sql_db.cc:

  Try to make sure DROP DATABASE does not cause a deadlock because we now let InnoDB wait MySQL does not have open handles to tables we drop


sql/sql_db.cc:
  Try to make sure DROP DATABASE does not cause a deadlock because we now let InnoDB wait MySQL does not have open handles to tables we drop
innobase/row/row0mysql.c:
  Try to make sure DROP DATABASE does not cause a deadlock because we now let InnoDB wait MySQL does not have open handles to tables we drop
parent 5f52ab10
...@@ -1802,6 +1802,7 @@ row_drop_database_for_mysql( ...@@ -1802,6 +1802,7 @@ row_drop_database_for_mysql(
char* name, /* in: database name which ends to '/' */ char* name, /* in: database name which ends to '/' */
trx_t* trx) /* in: transaction handle */ trx_t* trx) /* in: transaction handle */
{ {
dict_table_t* table;
char* table_name; char* table_name;
int err = DB_SUCCESS; int err = DB_SUCCESS;
...@@ -1812,12 +1813,27 @@ row_drop_database_for_mysql( ...@@ -1812,12 +1813,27 @@ row_drop_database_for_mysql(
trx->op_info = "dropping database"; trx->op_info = "dropping database";
trx_start_if_not_started(trx); trx_start_if_not_started(trx);
loop:
mutex_enter(&(dict_sys->mutex)); mutex_enter(&(dict_sys->mutex));
while (table_name = dict_get_first_table_name_in_db(name)) { while (table_name = dict_get_first_table_name_in_db(name)) {
ut_a(memcmp(table_name, name, strlen(name)) == 0); ut_a(memcmp(table_name, name, strlen(name)) == 0);
table = dict_table_get_low(table_name);
ut_a(table);
/* Wait until MySQL does not have any queries running on
the table */
if (table->n_mysql_handles_opened > 0) {
mutex_exit(&(dict_sys->mutex));
os_thread_sleep(100000);
goto loop;
}
err = row_drop_table_for_mysql(table_name, trx, TRUE); err = row_drop_table_for_mysql(table_name, trx, TRUE);
mem_free(table_name); mem_free(table_name);
......
...@@ -164,8 +164,6 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists) ...@@ -164,8 +164,6 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
} }
remove_db_from_cache(db); remove_db_from_cache(db);
ha_drop_database(path);
if ((deleted=mysql_rm_known_files(thd, dirp, path,0)) >= 0) if ((deleted=mysql_rm_known_files(thd, dirp, path,0)) >= 0)
{ {
if (!thd->query) if (!thd->query)
...@@ -191,6 +189,14 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists) ...@@ -191,6 +189,14 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
exit: exit:
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
/* It seems MySQL may call this function when there still are queries
running on tables of the database. Since InnoDB waits until the
queries have ended, we have to call ha_drop_database outside
the above two mutexes to avoid deadlocks. */
ha_drop_database(path);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment