MySQLのバージョンを8系から5系に落とした際のSQL起動エラー解決までの備忘録（The server quit without updating PID file ~~~）

## はじめに
こんにちは！(^O^)
[RUNTEQ](https://runteq.jp/)で、未経験からのWebエンジニア転職を目指して学習中のニョロニョロです🍄
この度、<b>〜毎日投稿イベント Advent Calendar 2022~</b>に参加させていただきました！
誤っている箇所や内容薄いところあれば、ドンドン教えていただけますと幸いですm(_ _)m

本記事は、mysqlのバージョンを8系から5系に落とした時に発生する、以下のエラー
```
$ brew services start mysql        
Password:
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/*.local.pid).
（`*`はMacのユーザー名です。）
```
の解決までに踏んだ手順をまとめています。

参考にさせていただいた記事は、一つの方法で解決した記事が多かったので、
自分が実行したコマンドとその結果、実際に自分が解決に至った手順などまとめてみました。
## 実行環境
```
$ sw_vers
ProductName:	macOS
ProductVersion:	12.3
BuildVersion:	21E230
$ mysql --version            
mysql  Ver 14.14 Distrib 5.7.39, for osx10.17 (x86_64) using  EditLine wrapper
```
macOSはM1チップで、
mysqlはrbenv経由ではなく、Home brew経由でインストールしています。
（macOSでもIntel版の方だと解決方法異なるかもしれません）
## 自分が解決までに行った手順

結論としては、4と5の手順で解決に至りました。
5の手順は、`/.bundle/config`にパスが入っていなかったことが原因だったので、
5の手順は必要ない方の方が多いかもしれません。

1. [PIDファイルについての解決記事](https://qiita.com/jonakp/items/477a18d4a94c01a31583)を参考に、PIDファイルの作成とPIDファイルに権限付与
 →PIDファイル作成できず、失敗

2. [プロセスについての解決記事](https://zenn.dev/ogakuzuko/articles/1d9d20fb5cbef8)を参考に、mysqlのプロセスを確認し、競合しているmysqlのプロセスあれば削除する
  →競合しているmysqlのプロセスなかった、失敗

3. [/tmpディレクトリの権限付与ついての解決記事](https://hituzi-ando.hatenablog.com/entry/2020/01/24/065731)を参考に、`tmp`ディレクトリに権限付与
   →権限元々付与されていたと思われる、失敗

4. [mysqlアンインストールについての解決記事](https://qiita.com/kazu_wsx/items/bb787e9e4e919da03705)を参考に、`brew uninstall mysql`では削除できないファイル群を削除する
  →mysql起動に成功！(ｲｴｲ)
    しかし、mysqlのgemを探すパスがbundlerに入っていないことで原因で、
`bundle install`できず

5. [.bundle/configにパスを通すための解決記事](https://qiita.com/fukuda_fu/items/463a39406ce713396403)を参考に、`open ssl`のインストールと
`bundle config`に`$ brew info openssl`の2つのパスを追記する
→`bundle install`成功！環境構築終了！(ｲｴｲ)

次の項目で、「自分のエラーログ」と「実行した手順とその結果」を見ていきます

## 自分のエラーログ
DB作成するために以下のコマンドを実行
```
$ bundle exec rails db:create
rails aborted!
LoadError: dlopen(/Users/*/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle, 0x0009): Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.21.dylib

~~~(長いので省略します)~~~

```
このエラーログは、[シンボリックリンクの解説記事](https://qiita.com/k-yasuhiro/items/9674d2e6e0b0fac3e1a8)で、詳しく解説がされており、

> シンボリックリンクにて、/usr/local/opt/mysql/lib/libmysqlclient.21.dylibファイルが見つからない為、エラーが起きている。

`シンボリックリンクとは`・・・UNIX系のOSにおいて、ファイルやフォルダに対する注文を代わりに受け付けて本来のファイルに中継するのを役目としている仲介役みたいなもの

つまり、DB作成するための`libmysqlclient.21.dylibファイル`
が見つからず、エラーが起こっている模様？？

少し、まだ理由が分からないので、mysqlが起動できている確認する。
```
$ brew services start mysql           
Password:
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/*.local.pid).
```
起動できていないようだ。。
どうやら`PID file`とやらが関係していそう。
ここで、先程触れた１〜５の実行した手順を行なっていく。

## 実行手順

### １. PIDファイルの作成とPIDファイルに権限付与

まず、上記エラーの
`. ERROR! The server quit without updating PID file`を紐解く。

その前に、PIDファイルってなんやねんってなったので、調べてみた。
`PIDとは`・・・プロセスID（Process ID）の略語で、
プロセスに割り振られた管理者用の番号のこと。
参考：[プロセスID(PID)とは](https://wa3.i-3-i.info/word11040.html)

プロセス??
という感じだったので、プロセスについても調べました。
`プロセスとは`・・・メモリを使って何かやっているプログラムひとつひとつのこと。
参考：[プロセスとは](https://wa3.i-3-i.info/word11032.html)

この事から、恐らく、mysqlを起動するプログラムの管理者番号ファイルにエラーがあるということ。[PIDファイルについての解決記事](https://qiita.com/jonakp/items/477a18d4a94c01a31583)を基にPIDファイルの作成とPIDファイルに権限付与を行なってみる。
```
$ touch /usr/local/var/mysql/*.local.pid

$ sudo chown -R _mysql:_mysql /usr/local/var/mysql/
```

結果、、mysql起動せずorz

どうやら、`touchコマンド`で、無理やりPIDファイル作成しても、PIDファイルすぐに消えてしまうなどの現象があるようです。
次に実行手順の2を行ってみます。

### 2. プロセスを確認し、競合しているプロセスあれば削除

[プロセスについての解決記事](https://zenn.dev/ogakuzuko/articles/1d9d20fb5cbef8)では、mysqlのプロセスを確認し、競合しているmysqlのプロセスあれば削除すれば、mysql起動できるとあった！！やってみよう！！

`$ ps aux | grep mysqlコマンド`でmysqlの文字列が含まれるプロセスを確認してみる。

ちょっと始めて使うコマンドなので調べてみる。
端的にまとめると、実行しているプロセスを、それをパイプで渡して、mysqlが入ったファイルのみ出力する感じ。
`ps aux`・・・実行しているプロセスを表示するコマンド
参考：[ps aux](https://masyus.work/articles/knowledge-linux-ps-aux/)
`grep`・・・ファイル中の文字列を検索するコマンド
参考：[grep](https://eng-entrance.com/linux-command-grep)
`パイプ(|)`・・・コマンドからコマンドへ出力した内容を橋渡しするコマンド
参考：[パイプ(|)](https://academy.gmocloud.com/know/20210630/12090#:~:text=%E3%83%91%E3%82%A4%E3%83%97%E3%81%A8%E3%81%AF%E3%80%81Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89,%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%82%87%E3%81%86%EF%BC%81)

`$ ps aux | grep mysql`を実行
```
$ ps aux | grep mysql
[ユーザー名]    896   0.0  1.1 35673196 182924   ??  S    11:35AM   0:05.70 /usr/local/opt/mysql@5.7/bin/mysqld --basedir=/usr/local/opt/mysql@5.7 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/opt/mysql@5.7/lib/plugin --log-error=*.local.err --pid-file=*.local.pid
[ユーザー名]    775   0.0  0.0 408509088   2816   ??  S    11:35AM   0:00.03 /bin/sh /usr/local/opt/mysql@5.7/bin/mysqld_safe --datadir=/usr/local/var/mysql
[ユーザー名]   4174   0.0  0.0 33725408   1192 s000  R+    5:14PM   0:00.00 grep mysql
```

どうやら、競合しているプロセスはなさそう。次に進む。

### 3. `/private/tmp`ディレクトリに権限を付与
続いて、[/tmpディレクトリの権限付与ついての解決記事](https://hituzi-ando.hatenablog.com/entry/2020/01/24/065731)を参考に`/private/tmp`ディレクトリに権限付与を行う。

`tmpディレクトリ`・・・一時的なファイルを置くディレクトリ。
参考：[tmpディレクトリ](https://linuc.org/study/knowledge/548/#:~:text=%E3%80%8C%2Ftmp%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%80%8D%E3%81%AF%E3%80%81,%E7%94%A8%E9%80%94%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)
通常は、権限が付与されているものらしいが、権限を付与し直すことで、mysqlが起動できる場合があるらしい。
一応念の為、`lsコマンド`で権限内容確認してみる
```
$ ls -la /private/tmp  
total 16
drwxrwxrwt  9 _mysql            _mysql  288 12 12 13:23 .
drwxr-xr-x  6 root              wheel   192 12 12 11:35 ..
drwx------  3 [ユーザー名]  wheel    96 12 12 11:35 com.apple.launchd.XXwpfANKYe
drwxr-xr-x@ 4 [ユーザー名]  _mysql  128 12 12 11:39 com.google.Keystone
d----w--w-  2 [ユーザー名]  _mysql   64 12 12 11:35 devio_semaphore_USB_Receiver@01120000
-rw-------  1 root              _mysql   36 12 12 11:35 fseventsd-uuid
srwxrwxrwx  1 [ユーザー名]  _mysql    0 12 12 11:35 mysql.sock
-rw-------  1 [ユーザー名]  _mysql    4 12 12 11:35 mysql.sock.lock
```
あまり分からない、、でも権限付与されているが、通常とのことなので、`chownコマンド`を使って権限付与してみる。
```
$ sudo chmod 1777 /private/tmp
Password:
$ ls -la /private/tmp         
total 16
drwxrwxrwt  9 _mysql            _mysql  288 12 12 13:23 .
drwxr-xr-x  6 root              wheel   192 12 12 11:35 ..
drwx------  3 [ユーザー名]  wheel    96 12 12 11:35 com.apple.launchd.XXwpfANKYe
drwxr-xr-x@ 4 [ユーザー名]  _mysql  128 12 12 11:39 com.google.Keystone
d----w--w-  2 [ユーザー名]  _mysql   64 12 12 11:35 devio_semaphore_USB_Receiver@01120000
-rw-------  1 root              _mysql   36 12 12 11:35 fseventsd-uuid
srwxrwxrwx  1 [ユーザー名]  _mysql    0 12 12 11:35 mysql.sock
-rw-------  1 [ユーザー名]  _mysql    4 12 12 11:35 mysql.sock.lock
drwxr-xr-x  2 root              _mysql   64 12 12 11:35 powerlog
```
変わったのだろうか？？

mysql起動できるか確認。。

できず。。( ・∇・)

next >>

### 4. `brew uninstall mysql`では削除できないファイル群を削除
`brew uninstall mysql`のみでは削除できないフォルダがあるらしい。
[mysqlアンインストールについての記事](https://qiita.com/kazu_wsx/items/bb787e9e4e919da03705)を、参考に`brew uninstall mysql`では削除できないファイル群を削除する。
```
$ brew uninstall mysql
$ rm -rf /usr/local/mysql
$ rm -rf /Library/StartupItems/MYSQL
$ rm -rf /Library/PreferencePanes/MySQL.prefPane
$ rm -rf /Library/Receipts/mysql-.pkg
$ rm -rf /usr/local/Cellar/mysql*
$ rm -rf /usr/local/bin/mysql*
$ rm -rf /usr/local/var/mysql*
$ rm -rf /usr/local/etc/my.cnf
$ rm -rf /usr/local/share/mysql*
$ rm -rf /usr/local/opt/mysql
```
> <b>補足：</b>
この時、
`brew uninstall mysql　@5.7`
や
`rm -rf /usr/local/mysql@5.7`
のようにバージョンを指定した方が良いかも。

`brew install mysql　@5.7`で、再度mysqlインストール.
続いて、mysqlを起動。

```
$ brew services start mysql@5.7
Service `mysql@5.7` already started, use `brew services restart mysql@5.7` to restart.
$ brew services restart mysql@5.7
Stopping `mysql@5.7`... (might take a while)
```
ん？なんか良さげ？？

`mysql -uroot`を実行

```
$ mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.39 Homebrew

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

キターー＼(^-^)／
無事に立ち上がりました。
続いて、`bundle exec rails db:create`でDB作成する。

```
$ bundle exec rails db:create
rails aborted!
LoadError: dlopen(/Users/*/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle, 0x0009): Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.21.dylib

~~~(長いので省略します)~~~

```

再度またこのエラー( ；∀；)でもmysql起動できた！
5に続きます。

### 5. `open ssl`のインストールと`bundle config`にパスの追記

結論としては、
原因は、mysqlのgemをインストールする際のパスが存在しないためであり、
解決方法としては、
・`open ssl`のインストール
・`bundle config`に`$ brew info openssl`の2つのパスを追記
することで、DBの作成までの環境構築が終了しました。
順を追って、行ったことを説明します。

`bundle doctor`を実行し、現在の状況を確認する。
```
$ bundle doctor
Bundler can't satisfy your Gemfile's dependencies.
Install missing gems with `bundle install`.
```

`bundle install`する必要がありそう。実行。

```
$ bundle install

〜〜（長いので省略します）〜〜

An error occurred while installing mysql2 (0.5.4), and
Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.4' --source 
'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2
```
とエラーログが出力され、mysql2がインストールできない模様。
`gem install mysql2 -v '0.5.4' --source 'https://rubygems.org/'`が成功するか確認してくださいとあるので実行。

```
$ gem install mysql2 -v '0.5.4' --source 'https://rubygems.org/'

〜〜（長いので省略します）〜〜

34 warnings generated.
linking shared-object mysql2/mysql2.bundle
ld: warning: directory not found for option '-L/usr/local/opt/openssl@3/lib'
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/[ユーザー名]/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.4 for inspection.
Results logged to /Users/[ユーザー名]/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-21/2.6.0/mysql2-0.5.4/gem_make.out
```

`ld: warning: directory not found for option '-L/usr/local/opt/openssl@3/lib'`
どうやら`openssl`に対応するディレクトがないことがエラーの原因の模様。

`open ssl`・・・暗号通信プロトコルであるSSLおよびTLSの機能を実装した、
オープンソースのライブラリのこと
参考：[Open SSLとは](https://www.designet.co.jp/faq/term/?id=T3BlblNTTA)

SSLやTLSのプロトコル使う際に必要なライブラリなのかなあと思いましたが、今まで入ってなかったことあるのだろうか。。とりあえず、インストールする。
`$ brew install openssl`
open sslをインストール。
次に、[.bundle/configにパスを通すための記事](https://qiita.com/fukuda_fu/items/463a39406ce713396403)を参考に、
`/.bundle/config`に通すパスを`$ brew info openssl`から持ってくる。

まずは、`$ brew info openssl`を実行
```
$ brew info openssl

〜〜（長いので省略します）〜〜

For compilers to find openssl@3 you may need to set:
→  export LDFLAGS="-L/usr/local/opt/openssl@3/lib"
→  export CPPFLAGS="-I/usr/local/opt/openssl@3/include"

For pkg-config to find openssl you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig"

==> Analytics
install: 444,212 (30 days), 1,417,472 (90 days), 6,155,261 (365 days)
install_on_request: 53,063 (30 days), 186,506 (90 days), 864,296 (365 days)
build_error: 0 (30 days)
```
上記の矢印のパス2つを`/.bundle/config`に追記する。

`$ open ~/.bundle/config`を実行。
開かれたファイルに上記矢印の2文を以下のように追記。
```
BUNDLE_BUILD__MYSQL2: "--with-LDFLAGS=-L/usr/local/opt/openssl@3/lib"
BUNDLE_BUILD__MYSQL2: "--with-CPPFLAGS=-I/usr/local/opt/openssl@3/include"
```

`$ bundle config`で確認。

```
$ bundle config                      
Settings are listed in order of priority. The top value will be used.
build.mysql2
Set for the current user (/Users/[ユーザー名]/.bundle/config): "--with-CPPFLAGS=-I/usr/local/opt/openssl@3/include"

path
Set for the current user (/Users/[ユーザー名]/.bundle/config): "vendor/bundle"
```
パス通ってそう。。
`$ bundle install`を実行

```
$ bundle install           
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...

〜〜（長いので省略します）〜〜

Installing mysql2 0.5.4 with native extensions
Bundle complete! 13 Gemfile dependencies, 64 gems now installed.
Bundled gems are installed into `./vendor/bundle`
```
できた！！！( ；∀；)

こちらで、MySQLのバージョンを8系から5系に落とした際のエラー解決備忘録、終了です！
長々とした文章拝見して下さってありがとうございましたm(_ _)m
少しでもお役に立つことができましたら、感服です！

## 参考記事一覧
[PIDファイルについての解決記事](https://qiita.com/jonakp/items/477a18d4a94c01a31583)
[プロセスについての解決記事](https://zenn.dev/ogakuzuko/articles/1d9d20fb5cbef8)
[/tmpディレクトリの権限付与ついての解決記事](https://hituzi-ando.hatenablog.com/entry/2020/01/24/065731)
[mysqlアンインストールについての解決記事](https://qiita.com/kazu_wsx/items/bb787e9e4e919da03705)
[.bundle/configにパスを通すための解決記事](https://qiita.com/fukuda_fu/items/463a39406ce713396403)
[シンボリックリンクの解説記事](https://qiita.com/k-yasuhiro/items/9674d2e6e0b0fac3e1a8)

参考：
[プロセスID(PID)とは](https://wa3.i-3-i.info/word11040.html)
[プロセスとは](https://wa3.i-3-i.info/word11032.html)
[ps aux](https://masyus.work/articles/knowledge-linux-ps-aux/)
[grep](https://eng-entrance.com/linux-command-grep)
[パイプ(|)](https://academy.gmocloud.com/know/20210630/12090#:~:text=%E3%83%91%E3%82%A4%E3%83%97%E3%81%A8%E3%81%AF%E3%80%81Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89,%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%82%87%E3%81%86%EF%BC%81)
[tmpディレクトリ](https://linuc.org/study/knowledge/548/#:~:text=%E3%80%8C%2Ftmp%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%80%8D%E3%81%AF%E3%80%81,%E7%94%A8%E9%80%94%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)
[Open SSLとは](https://www.designet.co.jp/faq/term/?id=T3BlblNTTA)

参考にさせていただき、ありがとうございました！m(_ _)m