MySQL道普請便り

第96回 Homebrewでbrew upgradeをしたあとにMySQLが起動しないときは

この記事を読むのに必要な時間:およそ 3 分

macOS上で開発環境を作る時に,ソフトウェアを管理する目的でパッケージマネージャであるHomebrewを利用している方も多いと思います。今回は,HomebrewでMySQLをアップグレードした際に発生したエラー .. ERROR! The server quit without updating PID file (/usr/local/var/mysql/MacBook-2.local.pid). を通して,トラブルの原因と対処方法について見ていきたいと思います。

実行環境

今回は,macOS Mojave上でHomebrewを導入している環境を前提に進めていきます。

Homebrewのインストールに必要な要素としては,以下のものになります。

  • Intel 64bit CPU
  • macOS 10.12以降
  • XCodeのCommand Line Tools(CLT)
    • xcode-select --installでインストール
  • bashまたはzshなどのBourne Shell互換のshellが存在している

これらの環境が整っている時に,以下のコマンドを実行すると,2018年4月25日時点ではHomebrewがインストールされます。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Homebrewを利用してMySQL5.7をインストールして利用していたときに,brew update && brew upgradeを行ったところ,8.0に更新され発生した事例を紹介します。

症状

brew update && brew upgrade mysqlを実行したあと,mysql.server startでMySQLを立ち上げようとすると以下のようなエラーが表示され,MySQLが起動できなくなることがありました。

$ mysql.server start
Starting MySQL
... ERROR! The server quit without updating PID file (/usr/local/var/mysql/MacBook2.pid).

この状態になってしまったら,とりあえずエラーログを確認してみましょう。エラーログは/usr/local/var/mysql/配下にあります。

$ cd /usr/local/var/mysql/

$ ls *.err
MacBook2.err

今回はMacBook2.errと言う名前でしたが,ホストや実行環境によって名前は変わると思うので適宜変更して実行してください。

tail -f MacBook2.err を行った状態で(err名は適宜置き換えて実行してください),別のターミナルからmysql.server startを実行して,どのようなエラーが表示されるか確認してみましょう。

$ tail -f MacBook2.err ←1つ目のターミナルで実行して待ちます

$ mysql.server start ←別のターミナルで実行します

起動に失敗した場合には1つ目のtail -fを実行しているターミナルに以下のようなエラーログが吐き出されます。

2019-04-26T00:46:19.6NZ mysqld_safe Logging to '/usr/local/var/mysql/MacBook2.err'.
2019-04-26T00:46:19.6NZ mysqld_safe Starting mysqld daemon with databases from /usr/local/var/mysql
2019-04-26T00:46:19.826171Z 0 [System] [MY-010116] [Server] /usr/local/Cellar/mysql/8.0.15/bin/mysqld (mysqld 8.0.15) starting as process 46527
2019-04-26T00:46:20.023930Z 1 [ERROR] [MY-012526] [InnoDB] Upgrade after a crash is not supported. This redo log was created with MySQL 5.7.18. Please follow the instructions at http://dev.mysql.com/doc/refman/8.0/en/upgrading.html
2019-04-26T00:46:20.023971Z 1 [ERROR] [MY-012930] [InnoDB] Plugin initialization aborted with error Generic error.
2019-04-26T00:46:20.332191Z 1 [ERROR] [MY-011013] [Server] Failed to initialize DD Storage Engine.
2019-04-26T00:46:20.333154Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
2019-04-26T00:46:20.334619Z 0 [ERROR] [MY-010119] [Server] Aborting
2019-04-26T00:46:20.337384Z 0 [System] [MY-010910] [Server] /usr/local/Cellar/mysql/8.0.15/bin/mysqld: Shutdown complete (mysqld 8.0.15)  Homebrew.
2019-04-26T00:46:20.6NZ mysqld_safe mysqld from pid file /usr/local/var/mysql/MacBook2.pid ended

今回のログで重要な情報は[ERROR]となっているところで,一番はじめの 2019-04-26T00:46:20.023930Z ~ の行になります。簡単に翻訳すると,⁠クラッシュ後からのアップグレードはサポートされていません。redoログはMySQL 5.7.25で作成されています。⁠と表示されています。

redoログは,公式のドキュメント中では以下のように説明がされています。

クラッシュリカバリ中に,不完全なトランザクションによって書き込まれるデータを訂正するために使用されるディスクベースデータ構造。通常の操作中に,InnoDBテーブルデータを変更するリクエスト (SQLステートメント,またはNoSQLインタフェースからの低レベルAPI呼び出しから発生) をエンコードします。予期しないシャットダウン前にデータファイルの更新を終了していない変更は,自動的に再現されます。

今回MySQLが起動できなかった環境では,開発目的でMySQLを実行しており,MySQLを正常に終了しないままOSのシャットダウンを行ったり,ノートパソコンのためバッテリー切れといった事態もたびたび発生していました。そのため,redoログが残ったままのクラッシュした状態からのアップグレードがサポートされていない状況でbrew upgradeを行った結果として,問題が発生してしまった模様です。

今回の場合の対処方法

開発データしかなくて手荒く行っても良いのであれば,データ自体をすべて削除して新しく作り直すという方法も取れますが,データをそのまま利用し続けるための方法としては,過去のバージョンに一度戻して正しくシャットダウンを行ってから再度起動し直すのが良いと思います。

Homebrewではbrew linkという機能を使って過去のバージョンに戻すことができるので,その機能を利用して過去のバージョンに戻します。

$ brew unlink mysql  ←現在のMySQL8をunlinkする
$ brew link --force mysql@5.7  ←MySQL5.7をlinkする
$ mysql.server start
Starting MySQL
.. SUCCESS!
$ mysql -uroot -p
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.25 Homebrew

…中略…

$ mysql.server stop

このように,MySQLのバージョンを一度戻してあげてからstopしましょう。正常に終了が完了すれば今回の問題は解決されました。その後に以下のような手順で最新のMySQLに変更して再度起動を試してみます。

$ brew unlink  mysql@5.7
$ brew link --force mysql
$ mysql.server start
Starting MySQL
.. SUCCESS!
$ mysql -uroot -p
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.15 Homebrew

ということで,今回問題であったredoログがなくなり,起動することができました。その他のMySQL8.0へのアップグレードでの注意点は,第76回の第76回 MySQL 8.0へのアップグレードに詳しい説明が載っているので割愛します。

まとめ

brew update && brew upgrade は個人の開発環境ではよく実行することがありますが,今回の例のように,MySQLが正常に終了していないと正しく動かないので注意をしましょう。

また,今回起動できない理由はredoログが原因でしたが,それ以外の場合も当然あります。MySQLが起動できなくなってしまった時には落ち着いてエラーログを見る習慣を付けると何が原因で起動できないのかがわかるようになるので,あまり起こってほしくはありませんが起動できない場合には,エラーログを確認してみてはいかがでしょうか。

著者プロフィール

木村浩一郎(きむらこういちろう)

株式会社オプティム 技術統括本部のエンジニア。最近はミドルウェア・インフラ周りのことも少しずつ学習しています。趣味は将棋。好きな戦法は四間飛車。

Twitter:@kk2170