Ubuntu19.10へのアップグレード後にDBD::mysqlでエラー発生
マイUbuntuサーバをUbuntu 19.10にアップグレードした後、毎日の体重をグラフ化したりするのに使用しているHRForecastが正常動作しておらず、エラーを出している事に気づきました。
起きた事
hrforecast.pl --config ./config.pl
を実行しているコンソールに出力されていたのは以下のようなメッセージでした。
install_driver(mysql) failed: Can't load '/opt/hrforecast-income/extlib/lib/perl5/x86_64-linux/auto/DBD/mysql/mysql.so' for module DBD::mysql: libmysqlclient.so.20: 共有オブジェクトファイルを開けません: そのようなファイルやディレクトリはありません at /home/bata64/.plenv/versions/5.28.1/lib/perl5/5.28.1/x86_64-linux/DynaLoader.pm line 193. at (eval 158) line 3. Compilation failed in require at (eval 158) line 3. Perhaps a required shared library or dll isn't installed where expected at /opt/hrforecast-income/extlib/lib/perl5/Scope/Container/DBI.pm line 69. at /opt/hrforecast-income/lib/HRForecast/Data.pm line 33. at /home/bata64/.plenv/versions/5.28.1/lib/perl5/5.28.1/Carp.pm line 291 Carp::croak('install_driver(mysql) failed: Can\'t load \'/opt/hrforecast-income/extlib/lib/perl5/x86_64-linux/auto/DBD/mysql/mysql.so\' for module DBD::mysql: libmysqlclient.so.20: M-eM-^EM-1M-fM-^\M-^IM-cM-^BM-*M-cM-^CM-^VM-cM-^BM-8M-cM-^BM-'M-cM-^BM-/M-cM-^CM-^HM-cM-^CM-^UM-cM-^BM-!M-cM-^BM-$M-cM-^CM-+M-cM-^BM-^RM-iM-^VM-^KM-cM-^AM-^QM-cM-^AM->M-cM-^AM-^[M-cM-^BM-^S: M-cM-^AM-^]M-cM-^AM-.M-cM-^BM-^HM-cM-^AM-^FM-cM-^AM-*M-cM-^CM-^UM-cM-^BM-!M-cM-^BM-$M-cM-^CM-+M-cM-^BM-^DM-cM-^CM-^GM-cM-^BM-#M-cM-^CM-,M-cM-^BM-/M-cM-^CM-^HM-cM-^CM-*M-cM-^AM-/M-cM-^AM-^BM-cM-^BM-^JM-cM-^AM->M-cM-^AM-^[M-cM-^BM-^S at /home/bata64/.plenv/versions/5.28.1/lib/perl5/5.28.1/x86_64-linux/DynaLoader.pm line 193.^J^@ at (eval 158) line 3.^JCompilation failed in require at (eval 158) line 3.^JPerhaps a required shared library or dll isn\'t installed where expected^J at /opt/hrforecast-income/extlib/lib/perl5/Scope/Container/DBI.pm line 69.^J') called at /opt/hrforecast-income/extlib/lib/perl5/Scope/Container/DBI.pm line 81 Scope::Container::DBI::connect('Scope::Container::DBI', 'dbi:mysql:hrforecast;hostname=127.0.0.1', 'bata64', 'XXXX') called at /opt/hrforecast-income/lib/HRForecast/Data.pm line 33 HRForecast::Data::dbh('HRForecast::Data=HASH(0x5589a8cd0748)') called at /opt/hrforecast-income/lib/HRForecast/Data.pm line 234 HRForecast::Data::get_complex('HRForecast::Data=HASH(0x5589a8cd0748)', 'money', 'Complex', 'income') called at /opt/hrforecast-income/lib/HRForecast/Web.pm line 110 HRForecast::Web::__ANON__('HRForecast::Web=HASH(0x5589a84b1848)', 'Kossy::Connection=HASH(0x5589a8aef700)') called at /opt/hrforecast-income/lib/HRForecast/Web.pm line 122 HRForecast::Web::__ANON__('HRForecast::Web=HASH(0x5589a84b1848)', 'Kossy::Connection=HASH(0x5589a8aef700)') called at /opt/hrforecast-income/extlib/lib/perl5/Kossy.pm line 179 Kossy::try {...} at /home/bata64/.plenv/versions/5.28.1/lib/perl5/site_perl/5.28.1/Try/Tiny.pm line 100 eval {...} at /home/bata64/.plenv/versions/5.28.1/lib/perl5/site_perl/5.28.1/Try/Tiny.pm line 93 Try::Tiny::try('CODE(0x5589a8aeeff8)', 'Try::Tiny::Catch=REF(0x5589a8aeee60)') called at /opt/hrforecast-income/extlib/lib/perl5/Kossy.pm line 185 Kossy::__ANON__('HASH(0x5589a8cc7388)') called at /opt/hrforecast-income/extlib/lib/perl5/Plack/Middleware/Scope/Container.pm line 14 Plack::Middleware::Scope::Container::call('Plack::Middleware::Scope::Container=HASH(0x5589a8ac9ef0)', 'HASH(0x5589a8cc7388)') called at /opt/hrforecast-income/extlib/lib/perl5/Plack/Component.pm line 50 Plack::Component::__ANON__('HASH(0x5589a8cc7388)') called at /opt/hrforecast-income/extlib/lib/perl5/Plack/Middleware/Static.pm line 18 Plack::Middleware::Static::call('Plack::Middleware::Static=HASH(0x5589a8aca0e8)', 'HASH(0x5589a8cc7388)') called at /opt/hrforecast-income/extlib/lib/perl5/Plack/Component.pm line 50 Plack::Middleware::StackTrace::try {...} at /home/bata64/.plenv/versions/5.28.1/lib/perl5/site_perl/5.28.1/Try/Tiny.pm line 100 eval {...} at /home/bata64/.plenv/versions/5.28.1/lib/perl5/site_perl/5.28.1/Try/Tiny.pm line 93 Plack::Middleware::StackTrace::call('Plack::Middleware::StackTrace=HASH(0x5589a8aca178)', 'HASH(0x5589a8cc7388)') called at /opt/hrforecast-income/extlib/lib/perl5/Plack/Component.pm line 50 Plack::Component::__ANON__('HASH(0x5589a8cc7388)') called at /opt/hrforecast-income/extlib/lib/perl5/Plack/Middleware/Lint.pm line 24 Plack::Middleware::Lint::call('Plack::Middleware::Lint=HASH(0x5589a8aca2b0)', 'HASH(0x5589a8cc7388)') called at /opt/hrforecast-income/extlib/lib/perl5/Plack/Component.pm line 50 Plack::Component::__ANON__('HASH(0x5589a8cc7388)') called at /opt/hrforecast-income/extlib/lib/perl5/Plack/Util.pm line 145 eval {...} at /opt/hrforecast-income/extlib/lib/perl5/Plack/Util.pm line 145 Plack::Util::run_app('CODE(0x5589a8aca268)', 'HASH(0x5589a8cc7388)') called at /opt/hrforecast-income/extlib/lib/perl5/Starlet/Server.pm line 366 Starlet::Server::handle_connection('Plack::Handler::Starlet=HASH(0x5589a8a95c90)', 'HASH(0x5589a8cc7388)', 'IO::Socket::INET=GLOB(0x5589a8cc6ef0)', 'CODE(0x5589a8aca268)', '', '', '') called at /opt/hrforecast-income/extlib/lib/perl5/Starlet/Server.pm line 190 Starlet::Server::accept_loop('Plack::Handler::Starlet=HASH(0x5589a8a95c90)', 'CODE(0x5589a8aca268)', 100) called at /opt/hrforecast-income/extlib/lib/perl5/Plack/Handler/Starlet.pm line 80 Plack::Handler::Starlet::run('Plack::Handler::Starlet=HASH(0x5589a8a95c90)', 'CODE(0x5589a8aca268)') called at hrforecast.pl line 77 install_driver(mysql) failed: Can't load '/opt/hrforecast-income/extlib/lib/perl5/x86_64-linux/auto/DBD/mysql/mysql.so' for module DBD::mysql: libmysqlclient.so.20: 共有オブジェクトファイルを開けません: そのようなファイルやディレクトリはありません at /home/bata64/.plenv/versions/5.28.1/lib/perl5/5.28.1/x86_64-linux/DynaLoader.pm line 193.
メッセージを精査すると「DBD::mysqlがlibmysqlclient.so.20を見つけられていない」という事が原因だとわかるのですが、発見した当初はCPANモジュールを入れ直したりplenv経由でPerlバージョンを5.30.0にしてみたりと遠回りをしてしまいました(いずれも改善せず)。
で、「libmysqlclient.so.20」が無いらしいという事がわかりましたので確認したところ、
$ ldd /opt/hrforecast-income/extlib/lib/perl5/x86_64-linux/auto/DBD/mysql/mysql.so linux-vdso.so.1 (0x00007ffdbc7e0000) libmysqlclient.so.20 => not found libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f033e2c3000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f033e0d2000) /lib64/ld-linux-x86-64.so.2 (0x00007f033e31d000)
という事で、確かにlibmysqlclient.so.20が見つからない模様。
更に
$ cd /usr/lib $ ls -l ./x86_64-linux-gnu/libmysqlclient.so* lrwxrwxrwx 1 root root 20 10月 9 22:03 ./x86_64-linux-gnu/libmysqlclient.so -> libmysqlclient.so.21 lrwxrwxrwx 1 root root 25 10月 9 22:03 ./x86_64-linux-gnu/libmysqlclient.so.21 -> libmysqlclient.so.21.1.17 -rw-r--r-- 1 root root 6776968 10月 9 22:03 ./x86_64-linux-gnu/libmysqlclient.so.21.1.17
という事で「libmysqlclient.so.21」はインストールされているが「libmysqlclient.so.20」は無いようです。
とりあえず「libmysqlclient.so.20」というシンボリックリンクを作ればいいかと思い
$ sudo ln -s libmysqlclient.so.21.1.17 libmysqlclient.so.20
してからhrforecastを起動してみましたが事象は改善せず。
ここで同様事象が報告されていないかGoogle検索してみたところ、
を発見。やっぱりまずはシンボリックリンクを作ってみるよね、と思いつつ、
というようにlibmysqlclient20のパッケージファイル(.deb)が公開されていたのでこれをダウンロードして
$ sudo dpkg -i ./libmysqlclient20_5.7.26-1_amd64.deb
でインストールしてからhrforecastを再度起動したところ正常に起動しました。
なお、参照した記事ではやっているapt installはいらんのでは(libmysqlclient20というlibmysqlclient21とは別のパッケージを入れたので)と思うので、とりあえずこのまま運用してみます。
考察
- アプリケーション稼働サーバでむやみにOSアップグレードするのは軽率(ただし反省はしていない)
- DBD::mysqlが将来アップデートされたら「libmysqlclient.so.21」を使うようになる?そうなったらこの事象は起きなくなるのではないか
では。