【问题标题】:How can I troubleshoot MySQL Lock Timeout Errors with Rails?如何使用 Rails 解决 MySQL 锁定超时错误?
【发布时间】:2012-09-15 18:10:03
【问题描述】:

突然之间(没有对相关代码进行任何更改)我们通过活动记录遇到锁定错误,例如:

ActiveRecord::StatementInvalid: Mysql2::Error: Lock wait timeout exceeded; 
try restarting transaction: UPDATE `items` SET `state` = 'reserved', `updated_at` = '2012-09-15 17:58:21' WHERE `items`.`id` = 248220

ActiveRecord::StatementInvalid: Mysql2::Error: Lock wait timeout exceeded; 
try restarting transaction: DELETE FROM `sessions` WHERE `sessions`.`id` = 41997883

我们没有在这两种模型中进行自己的交易,所以唯一的交易是内置的 rails 交易。流量或请求量没有激增。

这些错误似乎是当“新”查询尝试在锁定的表上运行并且必须等待时,我们如何查看它在等待什么?我们如何确定代码的哪一部分发出了长时间锁定表的查询?

关于我们可以在哪里寻找或如何调查其原因的任何想法?

【问题讨论】:

  • 您可以尝试像这样禁用间隙锁的方法: innodb_locks_unsafe_for_binlog=1 ,但它可能会导致一些幻像记录。阅读更多here
  • 底层数据库引擎是什么?如果它的 INNODB 可以发布“显示 innodb 状态”吗?
  • 显示引擎 INNODB 状态gist.github.com/3758910
  • 如果你可以复制这个,或者如果它经常发生,你可以在服务器上使用mysql命令客户端 MYSQL -u youruser -p 并运行 SHOW PROCESSLIST;命令,这将向您显示待处理的命令、等待锁定的命令等。您还可以运行 SHOW FULL PROCESSLIST;查看更多详情。

标签: mysql ruby-on-rails locking


【解决方案1】:

看看 pt-deadlock-logger,虽然与 rails 没有直接关系,但应该可以为您提供大量有关发生死锁的信息。

http://www.percona.com/doc/percona-toolkit/2.1/pt-deadlock-logger.html

有一篇很好的文章,里面有一些例子: http://www.mysqlperformanceblog.com/2012/09/19/logging-deadlocks-errors/

该工具非常简单实用。它监视 SHOW ENGINE INNODB STATUS 的输出并将新死锁记录到文件或我们以后可以查看的表中。让我们通过一个示例来看看它是如何工作的。

文章继续解释说,这可以记录有关死锁的信息,例如所涉及的查询、哪些主机、线程 ID 等。

我还发现使用 cmets 为查询添加前缀有助于跟踪,例如文件或模块、函数,甚至是哪个用户。查询 cmets 通常会一直传递给这样的诊断工具,并且可以帮助跟踪代码的哪些部分以及在哪些情况下导致死锁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-16
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 2015-09-20
    • 1970-01-01
    相关资源
    最近更新 更多