diff options
author | Jimmy Yang <jimmy.yang@oracle.com> | 2010-08-04 03:11:33 -0700 |
---|---|---|
committer | Jimmy Yang <jimmy.yang@oracle.com> | 2010-08-04 03:11:33 -0700 |
commit | 04970a2ff1d0019e256f12626c85266c3a0ebf35 (patch) | |
tree | 93447c5ac7a793786aaf087d7e3e69aecc6ffecc /storage/innobase/row | |
parent | 127ca525942e0e519f05fd5c01ca814738810db0 (diff) | |
download | mariadb-git-04970a2ff1d0019e256f12626c85266c3a0ebf35.tar.gz |
Fix Bug #54582 stack overflow when opening many tables linked with
foreign keys at once
rb://391 approved by Heikki
Z
Diffstat (limited to 'storage/innobase/row')
-rw-r--r-- | storage/innobase/row/row0mysql.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 4a834c4efc2..3b76ffa76f1 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); @@ -1597,6 +1607,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; @@ -2129,7 +2145,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) { @@ -3878,7 +3894,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); |