Bug #4446 | Server Crashes on DELETE which should cascade very deep | ||
---|---|---|---|
Submitted: | 8 Jul 2004 0:19 | Modified: | 16 Jul 2004 10:17 |
Reporter: | Thomas Kleffel | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
Version: | 4.0 | OS: | Linux (gentoo-linux i386) |
Assigned to: | Marko Mäkelä | CPU Architecture: | Any |
[8 Jul 2004 0:19]
Thomas Kleffel
[8 Jul 2004 1:41]
Thomas Kleffel
Just updated to 4.1.3-max, happens there as well.
[8 Jul 2004 1:43]
Thomas Kleffel
changed Version field to 4.1.3-beta-max
[8 Jul 2004 12:12]
Marko Mäkelä
I could repeat the crash with a tree structure that is 75 levels deep. It looks like InnoDB is calling itself recursively: row_upd_del_mark_clust_rec row_upd_clust_step row_upd row_upd_step row_update_cascade_for_mysql row_ins_foreign_check_on_constraint row_ins_check_foreign_constraint row_upd_check_references_constraints ...
[8 Jul 2004 16:31]
Heikki Tuuri
Marko, can you add some check to row0ins.c that would restrict the depth of the recursion to 50, for example? Regards, Heikki
[8 Jul 2004 22:31]
Marko Mäkelä
What should InnoDB do when that artificial limit is exceeded? Abort the transaction? I have another idea: set up a queue or stack data structure that holds those referenced key values that have not been processed yet. That should consume much less memory than the many stack frames currently needed for one recursion step.
[9 Jul 2004 17:38]
Heikki Tuuri
Marko, maybe it should treat the constraint as RESTRICT then? In practice that leads to the rollback to the SQL statement. We could also print a warning to the .err log. InnoDB already considers self-referential ON UPDATE CASCADE's as RESTRICT. Regards, Heikki
[13 Jul 2004 23:57]
Marko Mäkelä
Fix committed to 4.0 tree, waiting for approval. At most 49 levels of cascaded UPDATE or DELETE will be tolerated. The limit could probably be made much higher by not allocating table_name_buf[1000] from the stack, in row_ins_foreign_check_on_constraint().
[15 Jul 2004 14:26]
Marko Mäkelä
Each level of recursion consumes almost 4 kilobytes of stack space on x86. Removing table_name_buf[1000] from the stack reduces the consumption to less than 3000 bytes. After some discussion, Heikki and I decided to limit the recursion depth to 15 levels in order to avoid stack overflow on builds with small stack size. I'm submitting a new patch.
[16 Jul 2004 10:17]
Marko Mäkelä
Thank you for your bug report. This issue has been committed to our source repository of that product and will be incorporated into the next release. If necessary, you can access the source repository and build the latest available version, including the bugfix, yourself. More information about accessing the source trees is available at http://www.mysql.com/doc/en/Installing_source_tree.html Additional info: Fix pushed to the 4.0 tree, will appear in 4.1 after some time.