11

突然(関連するコードを変更せずに)、次のようなアクティブレコードを介してロックエラーが発生します。

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トランザクションのみです。トラフィックやリクエストの量は急増していません。

これらのエラーは、「新しい」クエリがロックされたテーブルで実行しようとして待機する必要がある場合に発生するようです。待機しているものをどのように確認できますか?コードのどの部分がテーブルを長期間ロックするクエリを発行しているのかをどのように把握しますか?

私たちがどこを見ることができるか、またはこれの原因を調査する方法についてのアイデアはありますか?

4

1 に答える 1

4

Rails とは直接関係ありませんが、pt-deadlock-logger を見てみると、発生しているデッドロックに関するかなりの量の情報が得られるはずです。

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 など、デッドロックに関する情報をログに記録できることを説明しています。

また、クエリの前にコメントを付けて、ファイルやモジュール、関数、さらにはどのユーザーなどを追跡できるようにすることも役立つことがわかりました。クエリ コメントは通常、このような診断ツールに渡され、コードのどの部分とどの状況でデッドロックが発生しているかを追跡するのに役立ちます。

于 2012-09-22T00:19:00.923 に答える