如何在非阻塞环境中修复此MySQL / Innodb死锁问题?

时间:2009-05-15 18:05:15

标签: mysql innodb

我们将MySQL与Innodb Engine存储结合使用。 我们有一个“事件”环境,可以在表上发送多个并发请求。 基本上,它的工作原理如下: 我们有一个find_or_insert函数来做到这一点: - 找() - >结果,如果为空 - >插入 - >在结果find()

我们使用非阻塞的MySQL驱动程序,所以基本上,当我们同时启动这个小算法不止一次时,它会在插入第一个结果之前运行所有发现......等等。

不幸的是,我们收到了以下错误: “尝试锁定时发现死锁;尝试重启事务”

任何人都可以提供帮助吗?

[编辑]:另外,我实际上不明白为什么MySQL需要锁定表只是为了在这里插入一个新元素。最初我虽然自动增量是罪魁祸首,所以我删除了它...我仍然得到错误。有没有办法防止MySQL在插入时锁定表?

3 个答案:

答案 0 :(得分:1)

尝试使用mysql reference manual进行诊断和解决。听起来你正在制作缓存。一个可能的原因可能是很多客户同时试图创建“第一个版本”(即点击'if empty insert')。也许你可以添加伪随机延迟或协调创建者,这样你就不会获得大量的并发创建调用?

编辑:您看过this页了吗?好像你需要设置my.cnf设置来禁用innodb的每表锁。我主要建议的是,你的测试可能无法表示,因为它可能包含比实际情况高得多的作者。如果您使用空表启动100个线程,它们将立即阻止创建(即使对于相同的值)。这比平均情况要糟糕得多,在这种情况下,您可以更好地传播密钥,更少的错误和更高的读取百分比。如果这是预期的行为(即你会有这种行为),我建议在create语句中添加一个退避策略。

答案 1 :(得分:0)

您需要一次发生这些请求,因此可能会停止使用该非阻塞驱动程序。或者实现自己的阻止机制。等待一个完成后再继续下一个。

你没有说这是不合理的,或者你出于某种原因需要这些东西如此迅速地移动。

答案 2 :(得分:0)

我正在改变我的回答,以反映问题已经修改。现在听起来这只是并发插入的问题,而不是对查找行为的依赖。

我的理解是InnoDB对插入进行了行锁定,你无法将其关闭。但是,您[编辑]无法使用INSERT DELAYED。我刚看到这个在InnoDB上没有。

http://dev.mysql.com/doc/refman/5.0/en/insert-delayed.html

也许围绕所有写入的显式LOCK TABLES将覆盖默认锁定行为。如果在写入事件发生的时间间隔内表上没有其他操作,则可能会有效。

http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html