summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSunanda Menon <sunanda.menon@oracle.com>2012-05-08 07:19:14 +0200
committerSunanda Menon <sunanda.menon@oracle.com>2012-05-08 07:19:14 +0200
commit074ce71e9022246fa466bbe28f6d15941a3d4cf3 (patch)
tree9d5910fc2367e588aff626fc7e5aeda06381a000 /storage
parente7364ec29c522b5d98951b851ca3cc62a9f46d59 (diff)
parentdf905524b218de07dddf5fa394af96edcc4ca483 (diff)
downloadmariadb-git-074ce71e9022246fa466bbe28f6d15941a3d4cf3.tar.gz
Merge from mysql-5.1.63-release
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/dict/dict0dict.c4
-rw-r--r--storage/innobase/handler/ha_innodb.cc5
-rw-r--r--storage/innobase/include/db0err.h2
-rw-r--r--storage/innobase/row/row0ins.c3
-rw-r--r--storage/innobase/row/row0mysql.c24
-rw-r--r--storage/innodb_plugin/dict/dict0dict.c4
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc4
-rw-r--r--storage/innodb_plugin/include/db0err.h2
-rw-r--r--storage/innodb_plugin/row/row0ins.c3
-rw-r--r--storage/innodb_plugin/row/row0mysql.c30
10 files changed, 81 insertions, 0 deletions
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index beea0a2f411..b2baa81b73f 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -26,6 +26,8 @@ Created 1/8/1996 Heikki Tuuri
#include "pars0sym.h"
#include "que0que.h"
#include "rem0cmp.h"
+#include "m_string.h"
+#include "my_sys.h"
#ifndef UNIV_HOTBACKUP
# include "m_ctype.h" /* my_isspace() */
#endif /* !UNIV_HOTBACKUP */
@@ -1889,6 +1891,8 @@ dict_foreign_free(
/*==============*/
dict_foreign_t* foreign) /* in, own: foreign key struct */
{
+ ut_a(foreign->foreign_table->n_foreign_key_checks_running == 0);
+
mem_heap_free(foreign->heap);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 20ab9c7a101..6576016501f 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -746,6 +746,10 @@ convert_error_code_to_mysql(
return(HA_ERR_RECORD_FILE_FULL);
+ } else if (error == (int) DB_TABLE_IN_FK_CHECK) {
+
+ return(HA_ERR_TABLE_IN_FK_CHECK);
+
} else if (error == (int) DB_TABLE_IS_BEING_USED) {
return(HA_ERR_WRONG_COMMAND);
@@ -4867,6 +4871,7 @@ ha_innobase::index_read(
DBUG_ENTER("index_read");
ut_a(prebuilt->trx == thd_to_trx(user_thd));
+ ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT);
ha_statistic_increment(&SSV::ha_read_key_count);
diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h
index bab6fa46370..1514b19639c 100644
--- a/storage/innobase/include/db0err.h
+++ b/storage/innobase/include/db0err.h
@@ -82,6 +82,8 @@ Created 5/24/1996 Heikki Tuuri
#define DB_REFERENCING_NO_INDEX 52 /* the parent (referencing) table does
not have an index that contains the
foreign keys as its prefix columns */
+#define DB_TABLE_IN_FK_CHECK 53 /* table is being used in foreign
+ key check */
/* The following are partial failure codes */
#define DB_FAIL 1000
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index bb5c95a572b..785a0426195 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -1074,6 +1074,9 @@ row_ins_foreign_check_on_constraint(
release the latch. */
row_mysql_unfreeze_data_dictionary(thr_get_trx(thr));
+
+ DEBUG_SYNC_C("innodb_dml_cascade_dict_unfreeze");
+
row_mysql_freeze_data_dictionary(thr_get_trx(thr));
mtr_start(mtr);
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 16fd2b3b482..6c2f910eec7 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -31,6 +31,8 @@ Created 9/17/2000 Heikki Tuuri
#include "btr0sea.h"
#include "fil0fil.h"
#include "ibuf0ibuf.h"
+#include "m_string.h"
+#include "my_sys.h"
/* A dummy variable used to fool the compiler */
ibool row_mysql_identically_false = FALSE;
@@ -1373,6 +1375,8 @@ row_update_for_mysql(
return(DB_ERROR);
}
+ DEBUG_SYNC_C("innodb_row_update_for_mysql_begin");
+
trx->op_info = "updating or deleting";
row_mysql_delay_if_needed();
@@ -3652,6 +3656,7 @@ row_rename_table_for_mysql(
ulint n_constraints_to_drop = 0;
ibool old_is_tmp, new_is_tmp;
pars_info_t* info = NULL;
+ ulint retry = 0;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
ut_a(old_name != NULL);
@@ -3750,6 +3755,25 @@ row_rename_table_for_mysql(
}
}
+ /* Is a foreign key check running on this table? */
+ for (retry = 0; retry < 100
+ && table->n_foreign_key_checks_running > 0; ++retry) {
+ row_mysql_unlock_data_dictionary(trx);
+ os_thread_yield();
+ row_mysql_lock_data_dictionary(trx);
+ }
+
+ if (table->n_foreign_key_checks_running > 0) {
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: Error: in ALTER TABLE ", stderr);
+ ut_print_name(stderr, trx, TRUE, old_name);
+ fprintf(stderr, "\n"
+ "InnoDB: a FOREIGN KEY check is running.\n"
+ "InnoDB: Cannot rename table.\n");
+ err = DB_TABLE_IN_FK_CHECK;
+ goto funct_exit;
+ }
+
/* We use the private SQL parser of Innobase to generate the query
graphs needed in deleting the dictionary data from system tables in
Innobase. Deleting a row from SYS_INDEXES table also frees the file
diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c
index ef3567c360d..df7ac85681c 100644
--- a/storage/innodb_plugin/dict/dict0dict.c
+++ b/storage/innodb_plugin/dict/dict0dict.c
@@ -24,6 +24,8 @@ Created 1/8/1996 Heikki Tuuri
***********************************************************************/
#include "dict0dict.h"
+#include "m_string.h"
+#include "my_sys.h"
#ifdef UNIV_NONINL
#include "dict0dict.ic"
@@ -2272,6 +2274,8 @@ dict_foreign_free(
/*==============*/
dict_foreign_t* foreign) /*!< in, own: foreign key struct */
{
+ ut_a(foreign->foreign_table->n_foreign_key_checks_running == 0);
+
mem_heap_free(foreign->heap);
}
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 30448bccf7b..ca6788999ae 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -868,6 +868,9 @@ convert_error_code_to_mysql(
case DB_OUT_OF_FILE_SPACE:
return(HA_ERR_RECORD_FILE_FULL);
+ case DB_TABLE_IN_FK_CHECK:
+ return(HA_ERR_TABLE_IN_FK_CHECK);
+
case DB_TABLE_IS_BEING_USED:
return(HA_ERR_WRONG_COMMAND);
@@ -5572,6 +5575,7 @@ ha_innobase::index_read(
DBUG_ENTER("index_read");
ut_a(prebuilt->trx == thd_to_trx(user_thd));
+ ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT);
ha_statistic_increment(&SSV::ha_read_key_count);
diff --git a/storage/innodb_plugin/include/db0err.h b/storage/innodb_plugin/include/db0err.h
index c7fa6d2a444..e4a3844cd22 100644
--- a/storage/innodb_plugin/include/db0err.h
+++ b/storage/innodb_plugin/include/db0err.h
@@ -97,6 +97,8 @@ enum db_err {
DB_FOREIGN_EXCEED_MAX_CASCADE, /* Foreign key constraint related
cascading delete/update exceeds
maximum allowed depth */
+ DB_TABLE_IN_FK_CHECK, /* table is being used in foreign
+ key check */
/* The following are partial failure codes */
DB_FAIL = 1000,
diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c
index 9a603d5690f..2d4afa6c5ed 100644
--- a/storage/innodb_plugin/row/row0ins.c
+++ b/storage/innodb_plugin/row/row0ins.c
@@ -1102,6 +1102,9 @@ row_ins_foreign_check_on_constraint(
release the latch. */
row_mysql_unfreeze_data_dictionary(thr_get_trx(thr));
+
+ DEBUG_SYNC_C("innodb_dml_cascade_dict_unfreeze");
+
row_mysql_freeze_data_dictionary(thr_get_trx(thr));
mtr_start(mtr);
diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c
index d67a7b29e1c..974d67893a3 100644
--- a/storage/innodb_plugin/row/row0mysql.c
+++ b/storage/innodb_plugin/row/row0mysql.c
@@ -52,6 +52,14 @@ Created 9/17/2000 Heikki Tuuri
#include "fil0fil.h"
#include "ibuf0ibuf.h"
+#ifdef __WIN__
+/* error LNK2001: unresolved external symbol _debug_sync_C_callback_ptr */
+# define DEBUG_SYNC_C(dummy) ((void) 0)
+#else
+# include "m_string.h" /* for my_sys.h */
+# include "my_sys.h" /* DEBUG_SYNC_C */
+#endif
+
/** Provide optional 4.x backwards compatibility for 5.0 and above */
UNIV_INTERN ibool row_rollback_on_timeout = FALSE;
@@ -1350,6 +1358,8 @@ row_update_for_mysql(
return(DB_ERROR);
}
+ DEBUG_SYNC_C("innodb_row_update_for_mysql_begin");
+
trx->op_info = "updating or deleting";
row_mysql_delay_if_needed();
@@ -3765,6 +3775,7 @@ row_rename_table_for_mysql(
ulint n_constraints_to_drop = 0;
ibool old_is_tmp, new_is_tmp;
pars_info_t* info = NULL;
+ ulint retry = 0;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
ut_a(old_name != NULL);
@@ -3848,6 +3859,25 @@ row_rename_table_for_mysql(
}
}
+ /* Is a foreign key check running on this table? */
+ for (retry = 0; retry < 100
+ && table->n_foreign_key_checks_running > 0; ++retry) {
+ row_mysql_unlock_data_dictionary(trx);
+ os_thread_yield();
+ row_mysql_lock_data_dictionary(trx);
+ }
+
+ if (table->n_foreign_key_checks_running > 0) {
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: Error: in ALTER TABLE ", stderr);
+ ut_print_name(stderr, trx, TRUE, old_name);
+ fprintf(stderr, "\n"
+ "InnoDB: a FOREIGN KEY check is running.\n"
+ "InnoDB: Cannot rename table.\n");
+ err = DB_TABLE_IN_FK_CHECK;
+ goto funct_exit;
+ }
+
/* We use the private SQL parser of Innobase to generate the query
graphs needed in updating the dictionary data from system tables. */