如何使用Rails解决MySQL Lock Timeout错误?

chr*_*mer 11 mysql locking ruby-on-rails

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

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
Run Code Online (Sandbox Code Playgroud)

ActiveRecord::StatementInvalid: Mysql2::Error: Lock wait timeout exceeded; 
try restarting transaction: DELETE FROM `sessions` WHERE `sessions`.`id` = 41997883
Run Code Online (Sandbox Code Playgroud)

我们没有在这两种模型中进行自己的交易,因此唯一的交易是内置轨道交易.流量或请求量没有激增.

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

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

sim*_*map 4

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

\n\n

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

\n\n

有一篇很好的文章,其中包含一些示例:\n http://www.mysqlperformanceblog.com/2012/09/19/logging-deadlocks-errors/

\n\n
\n

该工具非常简单且有用。它监视 SHOW ENGINE INNODB STATUS 的输出,并将新的死锁记录到文件或表中,以便我们稍后查看。让\xe2\x80\x99s 通过示例看看它是如何工作的。

\n
\n\n

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

\n\n

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

\n