[groonga-dev,03497] Re: Mroonga 5.06 特定のSQLにてメモリリーク傾向

Back to archive index

Kouhei Sutou kou****@clear*****
2015年 9月 14日 (月) 16:04:14 JST


須藤です。

In <CAOTaZHwCt-eOrBPknvr2K+-yN8UyJK_c6GJ5****@mail*****>
  "[groonga-dev,03496] Mroonga 5.06 特定のSQLにてメモリリーク傾向" on Mon, 14 Sep 2015 09:07:41 +0900,
  安福剛介 <gosuk****@gmail*****> wrote:

> Mroongaのストレージモードにて、
> 1つのSQLにて、MATCH AGAINTを2度使用し、LIMIT句をつけたケースにて、
> メモリリークの傾向が見られました。

報告ありがとうございます!
再現SQLもつけてもらって大変助かりました。

メモリーリークも該当SQLで期待通りの結果が返ってこない問題も
どちらも修正しました。今月末のリリースに含まれます。

もし、リリース前のこの修正が入ったコードを試してもらえるので
あれば、CentOS 6用のRPMをパッケージを提供します。

> まだ運用経験が少ないため、SQLの書き方が間違っているだけの可能性もござ
> いますが、
> ご相談させていただきたく投稿させていただきました。

まちがっていません!

ただ、注意点が1つあります。

mysqldumpでバックアップを取るときは、次のようにtest_tagsを
test_itemsよりも先にダンプしてください。

  % mysqldump DB test_tags > DB.dump.sql
  % mysqldump DB --ignore-table DB.test_tags >> DB.dump.sql

test_itemsが

  COMMENT 'table "test_tags"'

でtest_tagsを参照しているので、先にtest_tagsがリストアされる
ようにしないといけないのです。


mysqldumpはテーブル名でソートした順にダンプするみたいなので、
↑が面倒なら0_test_tagsみたいな名前のテーブル名にするのもあ
りかもしれません。(気持ち悪いですが。。。)

ただ、mysqldumpがテーブル名でソートした順に出すのは仕様とし
て決まっているわけではなさそう(単に、SHOW TABLESがそういう
挙動になっているからそうなっているっぽい)なので、
0_test_tagsは今後もうまく動くかはわかりません。。。


> 回避策、原因などご存知でしたら、
> どうぞよろしくお願いいたします。

回避策は最適化を無効にすることです。

  SET mroonga_enable_optimization = false;

参考: http://mroonga.org/ja/docs/reference/server_variables.html#mroonga-enable-optimization


原因は、MATCH AGAINSTが複数ある場合でも最適化を効かせていた
ことです。

MroongaはMATCH AGAINSTとORDER BYとLIMITがあるとMroonga内で
ORDER BYとLIMITを処理し、MySQLレベルでの処理を減らして高速化
しています。

  http://mroonga.org/ja/docs/tutorial/storage.html#optimisation-for-order-by-limit-in-full-text-search

MATCH AGAINSTが複数あったときはすべての結果のANDをとったうえ
でORDER BYしてLIMITする必要があるのですが、ANDではなくORをし
ていました。ORにするとヒットしていないレコードも含めてORDER
BYしてLIMITしてしまうのですが、そうするとMySQLレベルでヒット
していないレコードが除外されて結果が0件になってしまっていま
した。

解決方法ですが、↑の最適化を止めました。
最適化をやめるんじゃなくて、ORじゃなくANDするようにすればい
いじゃん、という考える人もいると思うんですが、MySQLからもらっ
ている情報が少なくて、今がANDするべきときかORするべきときか
を判断できない(*)ので、最適化自体をやめました。

(*) MroongaレベルでどのMATCH AGAINSTを処理しているか区別でき
    ないので↓というときにANDにするべきかORにするべきか判断
    できない
      MATCH() AGAINST() AND MATCH() AGAINST() OR MATCH() AGAINST()


-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード <http://www.clear-code.com/>

Groongaベースの全文検索システムを総合サポート:
  http://groonga.org/ja/support/
パッチ採用 - プログラミングが楽しい人向けの採用プロセス:
  http://www.clear-code.com/recruitment/
コードリーダー育成支援 - 自然とリーダブルコードを書くチームへ:
  http://www.clear-code.com/services/code-reader/




groonga-dev メーリングリストの案内
Back to archive index