summaryrefslogtreecommitdiff
path: root/storage/innobase/row/row0mysql.c
diff options
context:
space:
mode:
authorGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2010-10-05 11:11:56 +0300
committerGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2010-10-05 11:11:56 +0300
commit292a72a04376f4d7ebcf01de906b8346fb84f893 (patch)
treea085e87f237dac5a8cb4aa4f65520c7281c497ba /storage/innobase/row/row0mysql.c
parentd9f88e64f14124d568871c4418ce965026da3770 (diff)
parentb3cba906265eb7f3ae77d8b9069076b57e4e06c9 (diff)
downloadmariadb-git-292a72a04376f4d7ebcf01de906b8346fb84f893.tar.gz
merged mysql-5.1 into mysql-5.1-bugteam
Diffstat (limited to 'storage/innobase/row/row0mysql.c')
-rw-r--r--storage/innobase/row/row0mysql.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 2058363c786..a0f54f7288e 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -555,6 +555,12 @@ handle_new_error:
"forcing-recovery.html"
" for help.\n", stderr);
+ } else if (err == DB_FOREIGN_EXCEED_MAX_CASCADE) {
+ fprintf(stderr, "InnoDB: Cannot delete/update rows with"
+ " cascading foreign key constraints that exceed max"
+ " depth of %lu\n"
+ "Please drop excessive foreign constraints"
+ " and try again\n", (ulong) DICT_FK_MAX_RECURSIVE_LOAD);
} else {
fprintf(stderr, "InnoDB: unknown error code %lu\n",
(ulong) err);
@@ -1406,11 +1412,15 @@ row_update_for_mysql(
run_again:
thr->run_node = node;
thr->prev_node = node;
+ thr->fk_cascade_depth = 0;
row_upd_step(thr);
err = trx->error_state;
+ /* Reset fk_cascade_depth back to 0 */
+ thr->fk_cascade_depth = 0;
+
if (err != DB_SUCCESS) {
que_thr_stop_for_mysql(thr);
@@ -1602,6 +1612,12 @@ row_update_cascade_for_mysql(
trx_t* trx;
trx = thr_get_trx(thr);
+
+ thr->fk_cascade_depth++;
+
+ if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) {
+ return (DB_FOREIGN_EXCEED_MAX_CASCADE);
+ }
run_again:
thr->run_node = node;
thr->prev_node = node;
@@ -2134,7 +2150,7 @@ row_table_add_foreign_constraints(
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
- err = dict_load_foreigns(name, TRUE);
+ err = dict_load_foreigns(name, FALSE, TRUE);
}
if (err != DB_SUCCESS) {
@@ -2819,6 +2835,15 @@ row_truncate_table_for_mysql(
trx->table_id = table->id;
+ /* Lock all index trees for this table, as we will
+ truncate the table/index and possibly change their metadata.
+ All DML/DDL are blocked by table level lock, with
+ a few exceptions such as queries into information schema
+ about the table, MySQL could try to access index stats
+ for this kind of query, we need to use index locks to
+ sync up */
+ dict_table_x_lock_indexes(table);
+
/* scan SYS_INDEXES for all indexes of the table */
heap = mem_heap_create(800);
@@ -2891,6 +2916,10 @@ next_rec:
mem_heap_free(heap);
+ /* Done with index truncation, release index tree locks,
+ subsequent work relates to table level metadata change */
+ dict_table_x_unlock_indexes(table);
+
new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
info = pars_info_create();
@@ -3883,7 +3912,8 @@ end:
an ALTER, not in a RENAME. */
err = dict_load_foreigns(
- new_name, old_is_tmp ? trx->check_foreigns : TRUE);
+ new_name, FALSE,
+ old_is_tmp ? trx->check_foreigns : TRUE);
if (err != DB_SUCCESS) {
ut_print_timestamp(stderr);