部屋を掃除したら漫画が沢山出てきたので書く日記

漫画とか合唱とかUNIXとかLinuxとかについて書く日記です。

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検索してみたところ、

qiita.com

を発見。やっぱりまずはシンボリックリンクを作ってみるよね、と思いつつ、

launchpad.net

というようにlibmysqlclient20のパッケージファイル(.deb)が公開されていたのでこれをダウンロードして

$ sudo dpkg -i ./libmysqlclient20_5.7.26-1_amd64.deb

でインストールしてからhrforecastを再度起動したところ正常に起動しました。

なお、参照した記事ではやっているapt installはいらんのでは(libmysqlclient20というlibmysqlclient21とは別のパッケージを入れたので)と思うので、とりあえずこのまま運用してみます。

考察

  • アプリケーション稼働サーバでむやみにOSアップグレードするのは軽率(ただし反省はしていない)
  • DBD::mysqlが将来アップデートされたら「libmysqlclient.so.21」を使うようになる?そうなったらこの事象は起きなくなるのではないか


では。