もっとgroongaを知ってもらおう!ということで週刊groongaをはじめました。毎週木曜にgroongaやmroonga、rroongaのトピックを投稿予定です。
gihyo.jpさんでgroongaの隔週更新連載が始まっています。第10回の記事も公開されたので、一読をおすすめします。
第1回から第9回までの過去記事については、隔週連載groongaのページを参照してください。
はじめに
MySQLで高速に全文検索するためのオープンソースのストレージエンジンとしてmroonga (むるんが)を公開しています。
最新のバージョンは2013年8月29日にリリースした3.07です。
今回は、mroongaをアップグレードするときに、シンボルが未解決なため「Can't open shared library」エラーが発生してしまったときの対処方法を紹介します。
問題の内容
mroonga 3.07にアップグレードするときに、mroongaが意図せずアンインストールされるという不具合があり、暫定的な対処については、mroongaのリリースアナウンスでも紹介されています。
- [groonga-dev,01726] [ANN] mroonga 3.07 (アップグレードに関する不具合の告知あり)
- mroonga 3.07にアップグレードしたときのエラーでmroongaが意図せずアンインストールされる
それとは別に、アップグレード中に以下のようなエラーメッセージが表示されることがあります。
ERROR 1126 (HY000) at line 1: Can't open shared library '/usr/lib64/mysql/plugin/ha_mroonga.so' (errno: 2 undefined symbol: grn_expr_syntax_escape_query)
mroongaはgroongaをストレージエンジンとして使っているので、groongaで新規APIが追加されることがあります。
grn_expr_syntax_escape_query
はまさに、groonga 3.0.7で新規に追加されたAPIです。
mroonga 3.07にアップグレードするときに、groonga 3.0.7も一緒にアップグレードされるはずなのにどうしてこうなるのでしょうか。
まずは、エラーが発生したときのプロセスが使用中のファイルを確認してみることにしましょう。mroongaをアップグレードするときには、プラグインをアンインストールしてから、再度インストールするという手順を踏んでいます。lsofでmroongaが使用中になっているかを確認します。
$ sudo lsof -c mysql|grep mroonga
$
MySQLがプラグインのファイルであるha_mroonga.soを使用中というわけではなさそうです。では、mroongaが使用しているgroongaも確認してみましょう。
$ sudo lsof -c mysql|grep groonga
mysqld 13602 mysql DEL REG 253,0 2890926 /usr/lib64/libgroonga.so.0.0.0
lsofのTYPEがDEL
となっていました。 man lsofでドキュメントを確認してみるとマップファイルは削除されたけれども、という状態であることがわかりました。
or DEL for a Linux map file that has been deleted;
groongaのパッケージ自体は更新されているので、新しいlibgroonga.so.0.0.0が参照されるようにすれば良さそうです。
問題への対処方法
古いgroongaの共有ライブラリが参照されたままになっていることが問題であることがわかりました。そのため、この場合の対処としては、MySQLを再起動してからプラグインの再登録を行うのが良さそうです。
$ sudo service mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]
その後、mroongaを再度登録します。
$ mysql -u root -p -e "
USE mysql;
DROP FUNCTION IF EXISTS mroonga_snippet;
DROP FUNCTION IF EXISTS last_insert_grn_id;
DROP FUNCTION IF EXISTS mroonga_command;
DROP FUNCTION IF EXISTS mroonga_escape;
UNINSTALL PLUGIN mroonga;
FLUSH TABLES;
DELETE IGNORE FROM mysql.plugin WHERE name = 'mroonga';
INSTALL PLUGIN mroonga SONAME 'ha_mroonga.so';
CREATE FUNCTION last_insert_grn_id RETURNS INTEGER SONAME 'ha_mroonga.so';
CREATE FUNCTION mroonga_snippet RETURNS STRING SONAME 'ha_mroonga.so';
CREATE FUNCTION mroonga_command RETURNS STRING SONAME 'ha_mroonga.so';
CREATE FUNCTION mroonga_escape RETURNS STRING SONAME 'ha_mroonga.so';
"
再度、 lsofで確認してみましょう。
$ sudo lsof -c mysql|grep mroonga
mysqld 2010 mysql mem REG 253,0 273160 2892514 /usr/lib64/mysql/plugin/ha_mroonga.so.0.0.0
$ sudo lsof -c mysql|grep groonga
mysqld 2010 mysql mem REG 253,0 2228768 2890548 /usr/lib64/libgroonga.so.0.0.0
mysqld 2010 mysql 10w REG 253,0 468 1181820 /var/lib/mysql/groonga.log
TYPEがmemになっているので、共有ライブラリが再度読み込まれていることがわかります。
groonga 3.0.7で新規に追加されたAPIをmroonga_escapeが使っているので、以下のように動作確認を行うことができます。
mysql> select mroonga_escape("(仮)*", "()");
+--------------------------------+
| mroonga_escape("(仮)*", "()") |
+--------------------------------+
| \(仮\)* |
+--------------------------------+
1 row in set (0.00 sec)
きちんと結果を取得できていることがわかります。
まとめ
今回は、mroongaをアップグレードするときに、シンボルが未解決なため「Can't open shared library」エラーが発生してしまったときの対処方法を紹介しました。
mroongaの基本的な動作を知るためのユーザガイドもあります。インストールしたら試してみてください。