突然间(没有对相关代码进行任何更改)我们通过活动记录获得锁定错误,例如:
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
我们没有在这两种模型中进行自己的交易,因此唯一的交易是内置轨道交易。流量或请求量没有激增。
这些错误似乎是当“新”查询尝试在锁定的表上运行并且必须等待时,我们如何看待它正在等待什么?我们如何确定代码的哪一部分发出了长时间锁定表的查询?
有关我们可以查看的内容或如何调查原因的任何想法?
答案 0 :(得分:3)
看看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等。
我还发现使用注释为查询添加前缀有助于跟踪,例如文件或模块,功能,甚至是哪个用户。查询注释通常会一直传递给像这样的诊断工具,并且可以帮助跟踪代码的哪些部分以及导致死锁的情况。