代码之家  ›  专栏  ›  技术社区  ›  Julien Genestoux

如何在非阻塞环境中修复mysql/innodb死锁问题?

  •  1
  • Julien Genestoux  · 技术社区  · 16 年前

    我们将mysql与innodb引擎存储结合使用。 我们有一个“事件”环境,它在一个表上发送多个并发请求。 基本上,它是这样工作的: 我们有一个查找或插入函数,可以执行以下操作: -查找() ->打开结果(如果为空)->插入 ->在结果查找()时

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

    不幸的是,我们得到这些错误: “试图获取锁时发现死锁;请尝试重新启动事务”

    有人能帮忙吗?

    [编辑]:另外,我也不明白为什么MySQL只需要锁定表就可以在这里插入一个新元素。最初我认为自动增量是这里的罪魁祸首,所以我删除了它…但我还是有错误。有没有办法防止MySQL在插入时锁定表?

    3 回复  |  直到 16 年前
        1
  •  1
  •   Alexander Torstling    16 年前

    试试 mysql reference manual 用于诊断和解决。听起来像是在缓存。一个可能的原因是许多客户机同时命中表,试图创建“第一个版本”(即点击“if empty insert”)。也许你可以添加一个伪随机延迟或者协调创建者,这样你就不会有很多并发的对数据库的创建调用了?

    编辑:你看到了吗 this 第页?似乎您需要将my.cnf设置为使用innodb禁用每个表锁。不过,我主要建议的是,您的测试可能不具有代表性,因为它可能包含比实际情况高得多的编写者百分比。如果您用一个空表启动100个线程,它们都会在创建时立即阻塞(甚至可能为相同的值)。这比在平均情况下要糟糕得多,在这种情况下,您可以更好地分散密钥、更少的遗漏和更高的读取百分比。如果这是预期的行为(即您将使此行为处于活动状态),我建议在create语句中添加一个退避策略。

        2
  •  0
  •   Karl    16 年前

    您需要一次执行一个请求,所以可能停止使用该非阻塞驱动程序。或者实现自己的阻塞机制。在继续下一个之前,请等待一个完成。

    你没有说过这是不合理的,或者你出于某种原因需要这些东西这么快地向前发展。

        3
  •  0
  •   Walt Jones    16 年前

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

    据我所知,innodb对插入进行行锁定,您不能关闭它。但是,您[编辑]不能使用插入延迟。我刚读到InnoDB上没有这个。

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

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

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

    推荐文章