K’s diary

プログラミング、ビジネスや時事ニュース、経営/人事、音楽や映画について書いていきます

エラー「Incorrect MySQL client library version! This gem was compiled for 5.6.43 but the client library is 8.0.1」に対応した

はじめに

過去に作成したプロジェクトを編集する必要があり立ち上げた際に、MySQLに関するエラーが発生しました。

実は以前にも同じエラーで苦しめられた覚えがあります。その当時は訳が分からないままググって、出てきたコマンドをひたすらコピペ実行しまくり、何とか修正できました。が、エラー原因も対処法もわからずじまいでした。

なので、今回のエラーをきっかけに、MySQL他、Homebrew、rbenv、Bundler、LinuxUnixコマンドなどの基礎を改めて勉強しながら、エラーを対処しました。今回はその対処の手順の記録です。

記事の対象者(Who)

  • Ruby on rails 初学者
  • 同じエラーが発生して対処に困っている方

開発環境

何をするか(What)

Ruby on rails プロジェクトで、以下のMySQLエラーが発生したので対処した。

Incorrect MySQL client library version! This gem was compiled for 5.6.43 but the client library is 8.0.1

なぜ(Why)

  • MySQLエラーの原因を理解し解決するため
  • MySQL並びにエラー要因を理解し、対応に慣れるため

エラーの原因を分析してみる

以前(7ヵ月程前)に学習用に作成したプロジェクトを訳あって編集する必要が出た。

そこで、rails sでローカルサーバーを立ち上げようとすると、以下のエラーが発生した。

Incorrect MySQL client library version! This gem was compiled for 5.6.43 but the client library is 8.0.1

エラーの意味は「mysqlがバージョン5.6.43でコンパイルされてるけど、クライアントライブラリのバージョンは8.0.1になってるよ」とのこと。

そこでインストールしているMySQLの関連ファイルを確認すると、Cellerディレクトリにmysql@5.6とmysql8.0の両方が混在している。

<補足>

尚、Cellerディレクトリとは、Homebrewでインストールされたライブラリが格納されるディレクトリのことです。

(Homebrewについてもまた後日掲載したいと思っています。)

これは、直前に実装した別のプロジェクトで作業を行う過程で「brew upgrade」を行ったのが原因だと思われる。

<補足>

ちなみに「brew update」と「brew upgrade」の動作の違いは以下の通り。

brew update」・・・homebrewのverアップデート

brew upgrade」・・・homebrewのverアップデート+homebrewでインストールしたパッケージのverアップデート

brew upgrade」により、元々インストールしていたMySQL(5.6.43)の上位版(8.0.1)が自動的にインストールされてしまったと推測されます。

また、mysql@5.6系以下と8.0系とでは、認証用プラグインの仕様が変更になっているため、互換性が無いとのこと(ファイルが上書きされずに個別にインストールされるのは、その点への配慮でしょうか??)

そして、8.0.1がインストールされた際に、MySQLのclient library(MySQL本体を呼び出すためのライブラリ)も8.0系で上書きされてしまった。しかし、過去プロジェクトはMySQL(5.6.43)で作成しており、「mysql@5.6」用のclient libraryがコンパイルされている。どうやらそういうことらしいです。

対処の手順(How)

  • 今回のエラーは以下の方針で対処しようと思います。
  1. 2つの異なるバージョンを混在させたくないので一方を残し、一方を削除する

  2. 5.6系へのclient libraryへのシンボルリンクで上書きしたい&過去にイジり倒したシステム環境を整理したい

よって、まずはMySQLを全て削除してしまい、5.6系のみを再インストールすることにした。

  • 実行手順は以下の通り
  1. データベースの保存

  2. mysql動作確認&停止

  3. MySQLのアンインストール(5.6/8.0共に)&関連ファイルの削除

  4. mysql@5.6」のインストール&MySQLの設定

実行手順の詳細

まずはデータベースの保存 (長くなるので補足説明しません)

$ mysqldump -u root -p -x --all-databases > 任意のファイル名dump.sql

念のため、「ps(プロセス)コマンド」で動作しているMySQLのプロセスを確認します。

$ ps -ax | grep mysql

50319 ?? 0:00.04 /bin/sh /usr/local/opt/mysql@5.6/bin/mysqld_safe --datadir=/usr/local/var/mysql
50416 ?? 0:23.45 /usr/local/opt/mysql@5.6/bin/mysqld --basedir=/usr/local/opt/mysql@5.6 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/opt/mysql@5.6/lib/plugin --log-error=<name>-MacBook-Air.local.err --pid-file=<name>-MacBook-Air.local.pid

<補足> 「ps」の後の「ax」はコマンドオプションです。 a:端末操作プロセス、x:端末操作以外のプロセスで、動作中のプロセスのを網羅的に指定 「grep」は、指定した文字(mysql)が含まれている行だけを抽出するコマンド

では動いているMySQLサーバーを止めておきましょう。

$ mysql.server stop

Shutting down MySQL
.... SUCCESS!

では、MySQLをアンインストールしていきます(どきどき)

$ brew uninstall mysql@5.6
$ brew uninstall mysql
$ brew cleanup

これでMySQLがアンインストールされました。

では関連ファイルを削除していきましょう!

$ sudo rm -rf /usr/local/var/mysql
$ sudo rm -rf /usr/local/var/mysql56/
$ sudo rm -rf /usr/local/mysql*

<補足> sudoは須藤ではなく、Unix系OSのプログラムで、主にユーザーがsuperuser(すなわちroot)の特権レベルを利用して操作をする際に用いるコマンド rmはremoveでファイルやディレクトリの削除コマンド -rfはオプションです。詳細は調べてみましょう!

また、残っている不要ファイルを削除していきましょう(できれば目視で探しながら)。

# Homebrewでインストールした場合生成されるファイルを探して消す
$ sudo rm -rf /usr/local/Cellar/mysql*
$ sudo rm -rf /usr/local/bin/mysql*
$ sudo rm -rf /usr/local/var/mysql*
$ sudo rm -rf /usr/local/etc/my.cnf
$ sudo rm -rf /usr/local/share/mysql*
$ sudo rm -rf /usr/local/opt/mysql*
$ sudo rm -rf /etc/my.cnf

# その他の関連ファイルは、以下の環境設定ファイルもあれば探して削除しておきましょう
$ sudo rm -rf /Library/Receipts/mysql*
$ sudo rm -rf /Library/Receipts/MySQL*
$ sudo rm -rf /Library/StartupItems/MySQLCOM
$ sudo rm -rf /Library/PreferencePanes/My*
$ sudo rm -rf /private/var/db/receipts/*mysql*
$ sudo rm ~/Library/LaunchDaemons/com.oracle.oss.mysql.mysqld.plist
$ sudo rm ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist

MySQL自動起動設定をしている場合はそちらも解除しておきましょう

$ launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist

<補足> PCを立ち上げると同時に自動でMySQLサーバーを立ち上げるための設定です。詳細は調べてみましょう!

できればここでPCを再起動して、全てのMySQLプロセスを終了しておきましょう。(私は再起動しませんでした。また反省)

それではいよいよ、mysql@5.6のインストールしていきます。

$ brew install mysql@5.6

無事にインストールできましたか?では、MySQLを設定をしていきます。

$ echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.bash_profile
$ export LDFLAGS="-L/usr/local/opt/mysql@5.6/lib"
$ export CPPFLAGS="-I/usr/local/opt/mysql@5.6/include"

最後に、MySQL自動起動の設定をしておきましょう。

$ ln -sfv /usr/local/opt/mysql\@5.6/*.plist ~/Library/LaunchAgents
$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql@5.6.plist

完了ですね!ではMySQLサーバーを起動しましょう!

$ mysql.server start

Starting MySQL
... ERROR! The server quit without updating PID file (/usr/local/var/mysql/kanamaru-MacBook.local.pid).

!?

MySQLサーバーが立ち上がりません。ここで、念の為MySQLプロセスが動作していないか確認します。

$ ps aux | grep mysql

63646 0.0 0.2 4919136 8416 ?? S 8:54PM 0:01.40 /usr/local/opt/mysql@5.6/bin/mysqld --basedir=/usr/local/opt/mysql@5.6 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/opt/mysql@5.6/lib/plugin --log-error=MacBook-Air.local.err --pid-file=MacBook-Air.local.pid
63561 0.0 0.0 4279776 760 ?? S 8:54PM 0:00.03 /bin/sh /usr/local/opt/mysql@5.6/bin/mysqld_safe --datadir=/usr/local/var/mysql
69565 0.0 0.0 4295688 848 s000 S+ 9:43PM 0:00.01 grep mysql

なんか色々動いてそうなので、一旦全てのプロセスを強制終了します。

$ killall mysqld

そして、もう一度MySQLサーバーの起動にチャレンジ!

$ mysql.server start

Starting MySQL
SUCCESS!

動きました!ハァ〜。。。では、MySQLを入れ替えたので、一度データベースを再構築しようと思い、、

$ rake db:create

・・・中略・・・

rake aborted!
LoadError: dlopen(/Users/~/~/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/lib/mysql2/mysql2.bundle, 9): Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.21.dylib

はい、エラー出ました。エラー文をみると「clientlibrary.21」となっています。これはMySQL8.0系のものです(5.6系はclientlibrary.18)。

どういうことだ!?MySQLライブラリの関連ファイルを探しても「clientlibrary.21」は見つからず、正常に5.6系のみがインストールされています。

と、エラー文をよく見ると、、

.../Users/~/~/vendor/bundle/ruby/2.5.0/gems/mysql2-0.5.2/lib/mysql2/mysql2.bundle, 9)

とありますね。ここを直接見に行くとプロジェクトのgemファイル内にコンパイルされたMySQLライブラリでした。(これまで作業していたのはHomebrewでシステムにインストールされたMySQLライブラリ関連ファイルです。)

このコンパイルされたgemの中に「libmysqlclient.21.dylib」(mysql8.0系)へのリンクが生きているということでしょうか??何はともあれ、以下のコマンドで適切なライブラリへのシンボルリンクを貼ります。

$ sudo ln -s /usr/local/Cellar/mysql@5.6/5.6.43/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib

また「ln」はリンクの作成、「-s」はオプション「シンボルリンク(ショートカットみたいなもの)の作成」という意味になります。

「/usr/local/Cellar/mysql@5.6/5.6.43/lib/libmysqlclient.18.dylib」がリンク元のファイルのパス「/usr/lib/libmysqlclient.18.dylib」がシンボルリンクの名前です。

これで動きました!

その後、試しに新たにrails newして新規作成したプロジェクトも正常に動作することを確認。そして、過去に作成したプロジェクトも全て動き出しました!!

めでたしめでたし...

参考ページ

MySQL公式

Quiita記事:MacでMySQL5.7をアンインストール

どうしよう!困った時のMac上のMySQLのアンインストール&再インストール、動作確認手順

最後に

初めての投稿でかなり作成に時間がかかってしまいました。ブログを書くのも大変ですね。

今回勉強したMySQL、Homebrew、bundler、rbenvなどについても今後記事を作成していきたいと思っています。

またMarkdown記法をマスターすべく勉強中、もっと記事の数を増やして経験値を得るためにも、描きやすいライトな記事も作成していきたいと思っています(主にプログラミングやIT関連、時事関連記事を書いていきますが、たまに好きな音楽や映画に関すること、後禁煙日記もつけたいと思っています。)