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

Back to archive index

hiroshi hatake cosmo****@gmail*****
2015年 1月 17日 (土) 22:11:25 JST


畑ケです。

>>>> 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のこのバグを踏んでしまったというわけで
> す。
なるほど、詳細な解説ありがとうございます。
こちらでもJenkinsのログをあさってみた所、
12/21 〜 12/26の間のどこかでバグを踏むコードが入ったんだろうということが
分かりました。
で、実際にMariaDBのバグを踏んでいたコミットはこれみたいです:
https://github.com/mroonga/mroonga/commit/dd097fe207836863b1264894247f11b67fa69d2d

# もう少し頻繁にJenkinsを動かしていれば…と思いました。Windows用のCIを何
とかしたいですね。。。

> ちなみに、この処理は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に報告してもらえないでしょ
> うか?
>

報告しました!
https://mariadb.atlassian.net/browse/MDEV-7475

# この問題でCentOS 6.5も引っかかっているという認識でいいんでしょうか。。。




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