WSL上のUbuntuにMySQL 8.0をインストールする

WSL はとても便利ですが、MySQL に関してはいろいろ面倒なようで、MySQL を Ubuntu 18.04 LTS のデフォルトである MySQL 5.7 から 8.0 にアップグレードすると、なぜかうまくいかないことがあります(参考)。
一度色々なサイトを参考にしてどうにかしたつもりだったのですが、久々に sudo service mysql start したら [fail] と出てしまい長らく格闘したので、コマンド一式をメモ。

「インストール対象を MySQL 8.0 に設定した後 sudo apt install mysql-server でいけるっしょ」と思ってると痛い目に遭います…
WSL は Windows の互換を取るためか Systemd が使えず、Microsoft によってカスタムされた /init が使われるようです。
/init は Windows との様々な互換を取る一方、Systemd と比べると機能は少ないため、Systemd に依存するソフトは一工夫加えないと動かなかったりするとかが原因だそうで…
最新の LTS である Ubuntu 20.04 LTS は WSL1 上だと libc の変更云々の問題で 今のところ MySQL がインストールできません(こちらを参照)。
Windows 10 20H2 で修正されたそう ですが果たして…?

MySQL 8.0をアンインストールする

MySQL 8.0 を既にインストールしてしまっている場合は完全にアンインストールします。
少しでもデータや関連パッケージが残っているとうまくいかないようです。事前にデータは mysqldump でバックアップしておきましょう(忘れてやらかしたな…ってなった(最悪消えてもいいデータだったからあれだけど))

アンインストール中に「/var/lib/mysql/ を削除しますか?」という趣旨のダイヤログが表示されますが、事前に mysqldump でバックアップを取った上で「はい(もしくは Yes)」を選択します。

$ sudo apt purge mysql-server*
$ sudo apt purge mysql-client*
$ sudo apt purge mysql-common*
$ sudo apt autoremove --purge

私の環境だとインストール中に

mv: '/var/lib/mysql/.mysql.conf.backup' から '/etc/init/mysql.conf' へ移動できません: そのようなファイルやディレクトリはありません
dpkg: パッケージ mysql-community-server の処理中にエラーが発生しました (--remove):
installed mysql-community-server package post-removal script subprocess returned error exit status 1

という謎のエラーが出ましたが、この場合は mkdir /etc/init/ してあげてから再度実行するとうまくいきます。

インストール対象を MySQL 5.7 に変更する

WSL の場合、一旦 MySQL は 5.7 にダウングレードしてから 8.0 にアップグレードする必要があるようです。
mysql-apt-config を使い、インストール対象のパッケージを MySQL 5.7 に変更します。

$ wget https://dev.mysql.com/get/mysql-apt-config_0.8.15-1_all.deb
$ sudo dpkg -i mysql-apt-config_0.8.15-1_all.deb
$ sudo apt upgrade

ダイヤログが表示されるので、インストールする MySQL を 5.7 に変更して [OK] します。

$ sudo apt policy mysql-server
mysql-server:
  インストールされているバージョン: (なし)
  候補: 5.7.31-0ubuntu0.18.04.1
  バージョンテーブル:
*** 5.7.31-0ubuntu0.18.04.1 500
      500 http://jp.archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages
      500 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages
      100 /var/lib/dpkg/status
    5.7.21-1ubuntu1 500
      500 http://jp.archive.ubuntu.com/ubuntu bionic/main amd64 Packages

sudo apt policy mysql-server を実行し、MySQL 8.0 がバージョンテーブル内になければ大丈夫です。

MySQL 5.7 をインストールする

MySQL 5.7 をインストールします。

$ sudo apt install -y mysql-server

インストール後、sudo service mysql start を実行し、MySQL が起動できればひとまず OK です。

No directory, logging in with HOME=/
mkdir: ディレクトリ `//.cache' を作成できません: 許可がありません
-su: 19: /etc/profile.d/wsl-integration.sh: cannot create //.cache/wslu/integration: Directory nonexistent

という謎のエラーが出ることがありますが、MySQL 自体の起動に関係ないのでとりあえず無視します(後述)。

インストール対象を MySQL 8.0 に変更する

先ほどの mysql-apt-config を使い、今度はインストール対象のパッケージを MySQL 8.0 に変更します。

$ sudo dpkg -i mysql-apt-config_0.8.15-1_all.deb
$ sudo apt upgrade

ダイヤログが表示されるので、インストールする MySQL を 8.0 に変更して [OK] します。

$ sudo apt policy mysql-server
mysql-server:
  インストールされているバージョン: 5.7.31-0ubuntu0.18.04.1
  候補: 8.0.21-1ubuntu18.04
  バージョンテーブル:
*** 8.0.21-1ubuntu18.04 500
      500 http://repo.mysql.com/apt/ubuntu bionic/mysql-8.0 amd64 Packages
      100 /var/lib/dpkg/status
    5.7.31-0ubuntu0.18.04.1 500
      500 http://jp.archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages
      500 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages
    5.7.21-1ubuntu1 500
      500 http://jp.archive.ubuntu.com/ubuntu bionic/main amd64 Package

sudo apt policy mysql-server を実行し、MySQL 8.0 がバージョンテーブルの一番上にあれば大丈夫です。

MySQL 8.0 をインストールする

MySQL 8.0 をインストールします。
このとき、sudo apt upgrade だとうまくインストールできません。注意してください。

$ sudo apt install -y mysql-server

mysqld_safe_syslog.cnf を編集する

インストールはできたものの、sudo service mysql start を実行するとしばらく経った後に [Fail] と表示されてしまいます(参考)。
Stack eXchange 曰く、これは MySQL 8.0.13 以降、log_syslog が削除されたのにもかかわらず何故かインストール時に syslog を使う設定になってしまっているため発生する問題らしいです(そうはならんやろ)。

/etc/mysql/mysql.conf.d/mysqld_safe_syslog.cnf を開き、

[mysqld_safe]
syslog

[mysqld_safe]
#syslog

に変更・保存します。

もう一度 sudo service mysql start を実行し、[OK] と表示されれば起動できています。

サービス開始時のエラーをどうにかする

前述しましたが、service mysql startservice mysql restart を実行すると、

$ sudo service mysql restart
* Stopping MySQL database server mysqld [ OK ]
* Starting MySQL database server mysqld
No directory, logging in with HOME=/
mkdir: ディレクトリ `//.cache' を作成できません: 許可がありません
-su: 19: /etc/profile.d/wsl-integration.sh: cannot create //.cache/wslu/integration: Directory nonexistent
[ OK ]

という具合で謎のエラーが表示されます。実害はないので無視すればいい問題ではありますが、鬱陶しいし心臓に悪いのでどうにかしてみます(参考)。

/usr/share/wslu/wsl-integration.sh を開きます(/etc/profile.d/wsl-integration.sh/usr/share/wslu/wsl-integration.sh へのシンボリックリンク)。最初の行に、

WSL_INTEGRATION_CACHE=$HOME/.cache/wslu/integration

という記述があると思いますが、この行の前に

# Check if we have HOME folder
if [ "${HOME}" = "/" ]; then
    return
fi

を追記します。

# Check if we have HOME folder
if [ "${HOME}" = "/" ]; then
    return
fi

WSL_INTEGRATION_CACHE=$HOME/.cache/wslu/integration

if find -L $WSL_INTEGRATION_CACHE -newer /etc/resolv.conf 2> /dev/null | grep -q -m 1 '.'; then
(以下省略)

追記後のファイルはこのようになります。
もう一度 service mysql startservice mysql restart を実行してみて、エラーが消えれば OK です。

MySQL のユーザーフォルダを設定する

エラーは出なくなりましたが、依然として No directory, logging in with HOME=/ と表示されるのが気になります(参考)。

$ sudo grep mysql /etc/passwd
mysql:x:111:116:MySQL Server,,,:/nonexistent:/bin/false

ユーザーフォルダが /var/lib/mysql/(MySQL のデータフォルダ)に設定されていない (/nonexistent になっている) のが原因なので、

$ sudo service mysql stop
$ sudo usermod -d /var/lib/mysql/ mysql

と一旦 MySQL を止めた後に usermod でユーザーフォルダを設定してあげます。

$ sudo grep mysql /etc/passwd
mysql:x:111:116:MySQL Server,,,:/var/lib/mysql/:/bin/false

もう一度ユーザーフォルダを確認して /nonexistent が /var/lib/mysql/ に変わっていれば OK です。

service mysql start
* Starting MySQL database server mysqld [ OK ]

MySQL を起動し、メッセージが消えていればすべて完了です。お疲れ様でした。

コメント