[groonga-dev,03065] Re: MariaDBバンドル版Mroonga 4.09でMroongaがインストール出来ない問題について

Back to archive index

Kouhei Sutou kou****@clear*****
2015年 1月 16日 (金) 22:53:09 JST


須藤です。

In <54AFE****@gmail*****>
  "[groonga-dev,03061] Re: MariaDBバンドル版Mroonga 4.09でMroongaがインストール出来ない問題について" on Fri, 09 Jan 2015 23:41:35 +0900,
  hiroshi hatake <cosmo****@gmail*****> wrote:

>>> Visual Studio のデバッガで追って確認してみました。
>>>
>>> 手順)
>>> 1. Visual Studioのデバッガでmysqldをアタッチ
>>> 2. mysqlクライアントにshare\mroonga\install.sqlを食べさせる。
>>>
>>> すると、
>>>
>>>>   3964            ((o->flags & (PLUGIN_VAR_STR | PLUGIN_VAR_NOCMDOPT |
>>>>   3965 PLUGIN_VAR_MEMALLOC)) == PLUGIN_VAR_STR))

もう一度ソースを見たんですけど、これMariaDBのバグですねぇ。

MariaDB 10.0.15もそうですし、5.5.41もバグっています。

詳細を↓で説明するのでMariaDBに報告してもらえませんか?

↑のo->flagsにはinclude/mysql/plugin.hの↓をORで合わせて指定
します。

#define PLUGIN_VAR_BOOL         0x0001
#define PLUGIN_VAR_INT          0x0002
#define PLUGIN_VAR_LONG         0x0003
#define PLUGIN_VAR_LONGLONG     0x0004
#define PLUGIN_VAR_STR          0x0005
#define PLUGIN_VAR_ENUM         0x0006
#define PLUGIN_VAR_SET          0x0007
#define PLUGIN_VAR_DOUBLE       0x0008
#define PLUGIN_VAR_UNSIGNED     0x0080
#define PLUGIN_VAR_THDLOCAL     0x0100 /* Variable is per-connection */
#define PLUGIN_VAR_READONLY     0x0200 /* Server variable is read only */
#define PLUGIN_VAR_NOSYSVAR     0x0400 /* Not a server variable */
#define PLUGIN_VAR_NOCMDOPT     0x0800 /* Not a command line option */
#define PLUGIN_VAR_NOCMDARG     0x1000 /* No argument for cmd line */
#define PLUGIN_VAR_RQCMDARG     0x0000 /* Argument required for cmd line */
#define PLUGIN_VAR_OPCMDARG     0x2000 /* Argument optional for cmd line */
#define PLUGIN_VAR_MEMALLOC     0x8000 /* String needs memory allocated */

で、これの罠なのが、PLUGIN_VAR_BOOLからPLUGIN_VAR_DOUBLEは
フラグじゃない使いかたで、PLUGIN_VAR_UNSIGNED以降はフラグな
使い方なんです。

なので、

  (o->flags & (PLUGIN_VAR_STR | PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_MEMALLOC)) == PLUGIN_VAR_STR

という条件の

  o->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_MEMALLOC)

みたいにビット単位でORをしてそれをANDしたら0になるかどうかで
フラグが立っているかを確認するのはOKです。

しかし、

  (o->flags & PLUGIN_VAR_STR) == PLUGIN_VAR_STR

という使い方はNGです。

#define PLUGIN_VAR_STR          0x0005
#define PLUGIN_VAR_SET          0x0007

という定義になっているんですが、o->flagsが
PLUGIN_VAR_SETのときは↑の式は成り立ちます。

  (PLUGIN_VAR_SET & PLUGIN_VAR_STR) == PLUGIN_VAR_STR

がtrueになるということです。

これは、0x0007と0x0005をANDすると0x0005になるからです。

で、Mroonga 4.0.9から追加した
mroonga_boolean_mode_syntax_flagsは
PLUGIN_VAR_SETなんですよ。

  https://github.com/mroonga/mroonga/blob/master/ha_mroonga.cpp#L965

  static MYSQL_THDVAR_SET(boolean_mode_syntax_flags,

前述の通りPLUGIN_VAR_SETがPLUGIN_VAR_STRとして扱われてしまい
ます。しかし、PLUGIN_VAR_SET用の準備しかしていないので、
PLUGIN_VAR_STRとして扱われると変なところにアクセスしてしまい
ます。

ということで、MariaDBのこのバグを踏んでしまったというわけで
す。

ちなみに、この処理はMySQLにはなくてMariaDBにだけある処理なの
で、MySQLではクラッシュしません。


MariaDB 5.5.40用なんですが、参考までにパッチを張っておきます。
0x000fのところがダサいんですが、MariaDBの人ならもっとキレイ
にしてくれそうな気がします。

--- mariadb-5.5.40.orig/sql/sql_plugin.cc	2014-10-08 22:19:52.000000000 +0900
+++ mariadb-5.5.40/sql/sql_plugin.cc	2015-01-16 22:51:32.957073875 +0900
@@ -3916,8 +3916,8 @@
       we copy string values to a plugin's memroot.
     */
     if (mysqld_server_started &&
-        ((o->flags & (PLUGIN_VAR_STR | PLUGIN_VAR_NOCMDOPT |
-                       PLUGIN_VAR_MEMALLOC)) == PLUGIN_VAR_STR))
+        ((o->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_MEMALLOC)) == 0) &&
+        ((o->flags & 0x000f) == PLUGIN_VAR_STR))
     {
       sysvar_str_t* str= (sysvar_str_t *)o;
       if (*str->value)


と、こういうことなんですが、MariaDBに報告してもらえないでしょ
うか?

-- 
須藤 功平 <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