summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2004-12-27 17:15:38 +0200
committerunknown <heikki@hundin.mysql.fi>2004-12-27 17:15:38 +0200
commita7b984d2336135100c09998d653f331d3b9df996 (patch)
tree17ce705fa74b143093056c4ea2916547010a1e9c
parent50bd606d06ed549e0dbd5bbb2d35663fe7641421 (diff)
downloadmariadb-git-a7b984d2336135100c09998d653f331d3b9df996.tar.gz
row0ins.c:
Fix bug: if we dropped a table where an INSERT was waiting for a lock to check a FOREIGN KEY constraint, then an assertion would fail in lock_reset_all_on_table(), since that operation assumes no waiting locks on the table or its records row0mysql.c: Fix bug: InnoDB failed to drop a table in the background drop queue if the table was referenced by a foreign key constraint innobase/row/row0mysql.c: Fix bug: InnoDB failed to drop a table in the background drop queue if the table was referenced by a foreign key constraint innobase/row/row0ins.c: Fix bug: if we dropped a table where an INSERT was waiting for a lock to check a FOREIGN KEY constraint, then an assertion would fail in lock_reset_all_on_table(), since that operation assumes no waiting locks on the table or its records
-rw-r--r--innobase/row/row0ins.c26
-rw-r--r--innobase/row/row0mysql.c16
2 files changed, 37 insertions, 5 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index b9f860903cb..60dbf059673 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -1373,8 +1373,34 @@ row_ins_check_foreign_constraints(
row_mysql_freeze_data_dictionary(trx);
}
+ if (foreign->referenced_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ (foreign->referenced_table
+ ->n_foreign_key_checks_running)++;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
+ /* NOTE that if the thread ends up waiting for a lock
+ we will release dict_operation_lock temporarily!
+ But the counter on the table protects the referenced
+ table from being dropped while the check is running. */
+
err = row_ins_check_foreign_constraint(TRUE, foreign,
table, entry, thr);
+
+ if (foreign->referenced_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ ut_a(foreign->referenced_table
+ ->n_foreign_key_checks_running > 0);
+ (foreign->referenced_table
+ ->n_foreign_key_checks_running)--;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
if (got_s_lock) {
row_mysql_unfreeze_data_dictionary(trx);
}
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 2e8f7121d2c..ad5efc160c8 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -1761,6 +1761,12 @@ row_drop_table_for_mysql_in_background(
trx = trx_allocate_for_background();
+ /* If the original transaction was dropping a table referenced by
+ foreign keys, we must set the following to be able to drop the
+ table: */
+
+ trx->check_foreigns = FALSE;
+
/* fputs("InnoDB: Error: Dropping table ", stderr);
ut_print_name(stderr, name);
fputs(" in background drop list\n", stderr); */
@@ -1834,16 +1840,16 @@ loop:
goto already_dropped;
}
-
- if (table->n_mysql_handles_opened > 0
- || table->n_foreign_key_checks_running > 0) {
+
+ if (DB_SUCCESS != row_drop_table_for_mysql_in_background(
+ drop->table_name)) {
+ /* If the DROP fails for some table, we return, and let the
+ main thread retry later */
return(n_tables + n_tables_dropped);
}
n_tables_dropped++;
-
- row_drop_table_for_mysql_in_background(drop->table_name);
already_dropped:
mutex_enter(&kernel_mutex);