MySQL:超出最大深度的外键约束

时间:2012-12-14 07:16:52

标签: mysql foreign-keys sql-delete cascading-deletes

我在生产服务器上安装了MySQL Server 5.1.62。我每天都在监视mysql服务器的错误日志文件,突然间我在错误日志文件中发现了以下错误。

  

InnoDB:无法删除/更新超过最大深度为250的级联外键约束的行       请放弃过多的外来约束,然后再试一次

我有一个带有主键 - 外键关系的数据库结构以及正确的更新/删除操作,如果父表中的数据被应用程序或手动删除(后端),我需要删除子表的数据)。

我曾搜索过这个问题,但我找不到合适的解决方法。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:3)

看一下这个链接 - Cascade Delete results in "Got error -1 from storage engine"。有一个建议。

此外,作为一种解决方案,您可以尝试在没有 ON DELETE CASCADE 选项的情况下执行此操作,只需使用DELETE语句从一些表中删除记录(多表语法< / em>的)。

答案 1 :(得分:3)

模式的图片不是很有用,因为它没有显示任何级联声明。例如,如果删除应该从tbl_indentmaster级联到tbl_tepdetails,但删除应该从tbl_tepdetails级联到tbl_tepnoting,那么我希望某些删除失败。 (但是有不同的错误信息。)

如果引起这种情况的循环引用约束,我希望它部分是由tbl_indentmaster到tbl_tepdetails的级联引用引起的。您可能希望尝试删除该外键约束以进行测试。在tset服务器上执行此操作,而不是在生产服务器上执行此操作。

如果突然启动,并且您的数据库之前工作正常,我首先考虑

  • 从备份还原数据库,或
  • 从备份恢复架构,然后重新加载当前数据,或
  • 检出当前版本并重建数据库。 (你确实有database schema under version control,不是吗?)

我假设您没有良好的备份,并且您没有版本控制下的架构。

你是从一个好的数据库开始的吗?运行mysqlcheck。仔细阅读该文档。在获得经过测试的良好备份之前,请不要--repair

假设你的数据库是好的,那个级联删除应该在你的数据库中正常工作,并且你的Google技能很好,我认为你最好开始

  • 在测试服务器上安装MySQL 5.5或5.6,
  • 将数据库加载到该测试服务器上,
  • 看看您是否可以重现该特定错误。

要将数据库加载到测试服务器上,请使用mysqldump转储内容。不要在文件系统级别复制文件 - 其中一个或多个可能已损坏。

虽然此可能无法解决您的问题,但可能会告诉您问题的确切位置。如果它正常工作,您知道问题可能与服务器版本有关,并且可能通过版本升级解决。

答案 2 :(得分:1)

我同意@Devart和@Catcall的原始答案,但我想在与OP交换一些评论之后添加一些内容。

首先,我已将架构图像表示缩减为仅受DELETE上的tbl_indentmaster查询影响的表格。

从我看到的结构图中有 no 循环FK引用。

此外,OP运行以下查询:

DELETE FROM tbl_indentmaster WHERE indentId IN (1,2,3,4,5,6,...,150,151,155,156,....)

这是要删除的大量行。在进一步询问OP时,声称该查询适用于indentId的较小子集。

由此我认为我们可以采取两种可能性:

  1. MySQL中存在一个错误(极不可能但可能),导致像您这样CASCADE DELETE的大查询失败。注意我建议错误的可能性那个[已经发布] [2]。理想情况下,要删除的行数不重要。
  2. indentId中有一个特定的tbl_indentmaster条目导致整个查询失败。
  3. 我建议您首先尝试诊断问题,因为第(2)点是实际的罪魁祸首。您可以将DELETE查询分解为更小的块并找到有问题的ID。

    如果这个脚本必须通过代码定期执行(在更大的应用程序中),那么你应该考虑在那里以较小的块执行查询(每个查询可能有15个id是一个很好的开始IMO)。除了这样做之外,我建议在日志文件中记录错误id的错误,这样你就可以准确地知道哪些条目失败了。