Lock wait timeout exceeded を再現させる条件

1,001 views
Skip to first unread message

佐野水香

unread,
Mar 15, 2016, 11:06:42 PM3/15/16
to Redmine Users (japanese)

初心者です。申し訳ございませんが、どなたかご教授ください。


以下のログがproduction.logに多発して、メモリのリソースを大幅に消費する障害が頻発します。

ActiveRecord::StatementInvalid(Mysql2::Error: Lock wait timeout exceeded; try restarting transaction: SELECT `issues`.*FROM `issues` OORDER BY `issues`.`rgt` desc LIMIT 1 FOR UPDATE):
lib/plugins/awesome_nested_set/lib/awesome_nested_set/model.rb:165:in `right_most_bound`
lib/plugins/awesome_nested_set/lib/awesome_nested_set/model.rb:182:in `set_default_and_right`
app/models/issue.rb:165:in `create_or_update`
app/controllers/issues_controller.rb:150:in `create`

redmine Defect #6579と同様の問題かと思い、ツリー構造が複雑なサブチケット上でテストで更新をしてみたのですが、再現できません。
再現できなければ、redmineのバージョンアップを提案することも難しいので困っています。
どうか、どなたか、この障害が再発する条件を教えて頂けませんでしょうか?


redmineバージョン 2.6.0です。

あきぴー

unread,
Mar 17, 2016, 8:45:44 AM3/17/16
to Redmine Users (japanese)
はじめまして。あきぴーと申します。
佐野さんの環境の詳細が分からないので、以下は憶測で書きますので、ご了承ください。

(1)佐野さんの指摘通り、下記チケットに記載されているように、チケットが深い階層構造になっている場合に
ツリー上のチケットを更新する時に発生しているように思います。
佐野さんのRedmineでも、深い階層構造のチケットIDがログに記載されていないでしょうか?

Defect #6579: Tree hierachy being currupted on multiple submissions of an issue - Redmine 

Defect #17430: Broken Subtask Tree - Redmine 

例えば、チケットの階層が30個ぐらいとした場合、ツリー上のチケットに10M以上の添付ファイルを添付しようとして、
チケット更新に時間がかかる時に、MySQLに行ロックが掛かります。
そのタイミングで、同じツリー上の別チケットを更新しようとすると、ロックが外れないので、待ち状態が発生し、
タイムアウトが発生するのではないでしょうか。

上記チケットは、Ver2.1~2.4で再現しているようで、Ver3.0.0で解決されているので、Redmine本家の
チケットを元に説明されて、バージョンアップを提案されてはいかがでしょうか?

(2)Redmine本体が悪いというよりも、Redmineのチューニングに解決方法があるように思いました。
@akahane92さんがRxTStudyで公開されている下記資料を参考にしてはいかがでしょうか?
100万チケットでもRedmineが使えるようなMySQLの設定方法が記載されています。

Redmineチューニングの実際と限界 

Setting_paramaters_for_Redmine_Performance_Tuning.txt 

(3)佐野さんの症状とは無関係ですが、プロジェクトの階層構造が深い場合も同様に、
階層が上手く保存されない症状があると下記チケットに記載されています。
Ver3.3.0で解決予定です。

Patch #21611: Do not collect ids of subtree in Query#project_statement - Redmine 
http://www.redmine.org/issues/21611

Defect #19976: Redmine can't work with 3000 projects - Redmine 
http://www.redmine.org/issues/19976

普通は3000個ものプロジェクトや深い階層構造のプロジェクトは作らないでしょうが、
Redmineの多種多様な運用事例があるのだろうと思います。

2016年3月16日水曜日 12時06分42秒 UTC+9 佐野水香:

松谷秀久

unread,
Mar 17, 2016, 10:17:36 AM3/17/16
to Redmine Users (japanese)
はじめまして。

松谷と申します。

再現方法ではないですが、書かれているエラーメッセージから、awesome_nested_setで問題が発生していると思われます。

https://www.redmine.org/issues/18860

によると、Redmine 3.0.0 にて awesome_nested_setを単純で強固な独自の実装で置き換える、という対策がされており、
これによって、いくつかのdead lockの問題を修正しているようですので、3.0.0以上にバージョンアップするという対策が有効なのではないかとおもいます。

簡単ですが、以上です。

佐野水香

unread,
Mar 21, 2016, 10:19:07 PM3/21/16
to Redmine Users (japanese)
あきぴーさん

ご親切なご説明ありがとうございました!!
特殊なケースで、再現するということが、よくわかりました。
Redmine本家のフォーラムでも書き込んだのですが、丸山さんという方が
「select * from issues for update;」したら、簡単に再現するよということだったので
実行したら、(当然??)再現できました。

RedmineのバージョンアップかMySQLのチューニングか検討中で、
対処後に、また再現テストをしなければいけないのですが
あきぴーさんの以下の例を参考にテストケースを作ろうと思います。


> 例えば、チケットの階層が30個ぐらいとした場合、ツリー上のチケットに10M以上の添付ファイルを添付しようとして、
> チケット更新に時間がかかる時に、MySQLに行ロックが掛かります。

佐野


2016年3月17日木曜日 21時45分44秒 UTC+9 あきぴー:

佐野水香

unread,
Mar 21, 2016, 10:23:35 PM3/21/16
to Redmine Users (japanese)
松谷さん

ご回答ありがとうございます!!
awesome_nested_set の問題は、Redmine本家のチケットで読んだのですが
よく意味がわからなくて、松谷さんに簡潔に説明していただいて大変助かりました。
Redmine のバージョンアップは少しハードルがあるのですが、提案してみようと思います

佐野

2016年3月17日木曜日 23時17分36秒 UTC+9 松谷秀久:

あきぴー

unread,
Mar 22, 2016, 8:48:36 AM3/22/16
to Redmine Users (japanese)
こんばんは、あきぴーです。
Redmine本家で、Redmineコミッタのまるやまさんが回答されて、解決されて良かったですね。
一言コメントします。

(1)「Redmineのチケット・プロジェクトの階層構造が無限の階層で作成できる」という仕様は、
「RDBの入れ子集合モデル」というアルゴリズムで実現されています。
Issuesテーブルのlft, rgtというカラムが存在する理由が、それに該当します。
入れ子集合モデルは、下記の記事が分かりやすいです。

第5回 SQLで木構造を扱う~入れ子集合モデル (1)入れ子集合モデルとは何か :SQLアタマアカデミー|gihyo.jp … 技術評論社

ちなみに、「awesome_nested_set」は、Rubyで入れ子集合モデルを実現するためのGemライブラリみたいです。

Railsでawesome_nested_setを使って階層構造を作成する - Rails Webook

(2)入れ子集合モデルでは、階層構造に属するレコードが1件でも修正が発生すると、
階層構造の配下にある全てのレコードを更新するため、データ更新の影響範囲が大きくなります。
実際、Issuesテーブルの対象レコードに対し、lft, rgtというカラムを全て更新しなくてはならないのです。

そのような仕様を踏まえると、佐野さんが遭遇した現象は、チケットが深い階層構造になっていて、
階層構造の配下のチケットの枚数が相当たくさんある状態で、該当チケットを更新しようとして、
デッドロックが発生したのではないか、と推測します。
普通はデッドロックが発生しないので、常識以上に深くネストされたチケット構造ではないか、と推測します。

そういう入れ子集合モデルの弱点に対し、下記の記事では、Issuesテーブルのlft, rgtを整数値ではなく、
有理数を設定すれば、有理数の稠密性という特徴を使って解決できる、と紹介されています。
Redmineはそこまでは実現していないようです。

第6回 SQLで木構造を扱う~入れ子区間モデル (1)もしも無限の資源があったなら :SQLアタマアカデミー|gihyo.jp … 技術評論社


2016年3月22日火曜日 11時19分07秒 UTC+9 佐野水香:
Reply all
Reply to author
Forward
0 new messages