myfinderの技術や周辺的活動のblog

2009年2月12日木曜日

Q4Mを使うときにやってはいけない一つのこと

ある日Q4Mを利用したシステムを運用していたところ、プログラマの方から

「Q4Mのテーブルが壊れたっぽいのだけども。。。」

との報告があり、状況を聞いてみた。
どうも、Queueに突っ込んだけども処理したくないデータがあったという理由で一部の行をDELETEしたとのこと。

で、早速DBを調べてみると、全部queue_waitで取り出したにも関わらず行数が0にならなかったり、
発行しているqueue_endが実行されずにずっとプロセスが残っていたりして大変カオスな状態になっていた。
(insertも止まっていた)

その場ではMySQLを強制的に再起動して、tableやschemaをdropして再作成してもらうことでことなきを得た。
が、今日帰ってきてQ4Mのページを見て謎が解決。
Q4Mの「Limitations and Known Issues」に

removal of multiple rows from a single DELETE statement is not atomic
(複数行に対する一つのDELETE文による削除はアトミックじゃありません)

と書いてあるじゃありませんか。
というわけで、これからQ4Mを使いたいという方でもし

「Queueに入れたけどやっぱり処理させたくないものは取りやめる」

というような要件がある場合
  1. 1行1DELETE文で削除する。
  2. もしくはignoreテーブルとかを作ってQueueを特定する情報を突っ込んでおいて、dequeueした時にignoreと照合する。
  3. QUEUEストレージエンジンを利用するschemaと、それ以外のschemaは分ける。
    (あるいは別にMySQL5.0を用意してそっちに入れとく)
などの対策が必要になるかなと思います。

なので、Q4Mを使うときには

複数行に対して1つのDELETE文による削除はやってはいけない

です。
以上、ご参考まで〜

1 件のコメント:

kazuho さんのコメント...

"not atomic" というのは、複数行の削除を実行中に、他の (non-owner モードの) クライアントから SELECT を行うと、一部の行のみが削除されているように見える状態がある、ということを指しています。

テーブルが壊れるとしたら別の問題 (というかバグ) だと思います。すみません...

詳しい状況 (テーブルのスキーマとか壊れたときの行数とか発行してる SQL とか) を教えていただければ、ありがたいです。