MacのMySQL環境を整理した

## TL；DR

とりとめのない纏め。

MySQL 8.xと5.6のRailsプロジェクトが混在することになって、切替の必要がでてきた。
いろいろ試したけど、うまくできなかったので、一旦綺麗にすることにした。
ぶっちゃけ面倒なのでdocker-compose.yml書いた方が良さげ。

## 症状など
 - （過去うまくいかなかった時に）コピペ`sudo`したり`chown`したりで権限がよくわからなくなっていた
 - `ERROR! The server quit without updating PID file` みたいな、Macだと良くあるMySQLエラーから脱却できないくなった
 - `$ xcode-select --install` しても直らなかった
 - `$ ps aux | grep mysql` するとゾンビ化したプロセスが幾つかあったが、killしても蘇って殺せなかった（再起動で直った）

`brew upgrade`しただけで、ローカルに旧verのformulaが残っている場合、`brew switch`で切り替えることができる。現在どのverを使っているかは、`brew info`で確認することができる。とはいえ後から狙ったversionを追加していくのは面倒そうだったので、`brew service`で切り替える方法がマシっぽい。

つまり`mysql.server start`でなく`brew services start mysql@5.6`で起動する方法をとる。


## 綺麗にする

[brew services start mysql で mysql デーモンが起動しないと思ったら datadir が古かった](https://qiita.com/niwatako/items/6d79dd9b69443f4c021c)
↑を参考にスパッと消したらスッキリした。

```shell
# 古いやつは消す
$ brew uninstall mysql@5.6
$ brew uninstall mysql
# 残ってるdatadirをきれいにする
$ rm -rf /usr/local/var/mysql
$ rm -rf /usr/local/var/mysql56/
# 入れ直し
$ brew install mysql@5.6
# brew infoでecho文が提示されているので、必要ならパスを通しておく
$ echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.bash_profile
$ . ~/.bash_profile
# 起動テスト
$ mysql.server start
$ mysql.server stop
# launchctlに登録
$ brew services start mysql@5.6
# 動いていることを確認
$ launchctl list | grep mysql
10694   0   homebrew.mxcl.mysql@5.6
```

## 定期実行の登録

```shell
$ launchctl load 設定.plist # 登録
$ launchctl unload 設定.plist # 解除
$ launchctl list # 登録状況とそのPID一覧
```
plistの作成とload/unloadを同時に行うのがbrew service

```shell
$ brew services start mysql@5.6 # MySQLを常時起動する
$ brew services stop mysql@5.6 # MySQLの常時起動をやめる
$ launchctl list | grep mysql # MySQLが登録されていて動いていることを確認する
```

## MySQL 8.xも共存させる

2018-09時点では、普通に入れると8系が入る。

- `brew install mysql` # <- 8.x
- `brew install mysql@5.6`
- `brew install mysql@5.7`

```shell
$ brew install mysql
$ brew info mysql
# ...(前略)
# usr/local/Cellar/mysql/8.0.12 (255 files, 233.0MB) *
# (後略)...
```

問題は、ローカルに複数のバージョンのMySQLを入れた場合、mysql2 gemが`Library not loaded`エラーを吐いてRailsが起動できなくなってしまう。どうもmysql2 gemはインストール時点のMySQLクライントに依存するようで、いったんuninstallして入れ直す必要が生じるようだった。

```shell
$ bundle exec gem uninstall mysql2
$ bundle install
```

### 方法１: localに入れた複数Verを切り替える

[Multiple MySQL Versions with Homebrew](https://gist.github.com/benlinton/d24471729ed6c2ace731)

毎回unlink -> switchを打つ。

```shell
# Unlink current mysql version
brew unlink mysql 

# Check older mysql version
ls /usr/local/Cellar/mysql56 # => 5.6.27

# Link the older version
brew switch mysql56 5.6.27
```

メンドくさいし、すぐ忘れそう。


### DockerのMySQLを参照する

```shell
docker run -d --restart always --name mysql57 -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 mysql:5.7
```

任意のverのMySQLコンテナを立ち上げて、環境変数でRailsのMySQL接続先を`127.0.0.1` に向けて接続する（`localhost`と`127.0.0.1`は違う挙動をする。socketを探すかどうかなど）。変数名は環境によって異なるため、`/config/database.yml`等の設定を確認すること。

```.env
## MySQLの設定
DATABASE_HOST="127.0.0.1"
DATABASE_USER="root"
DATABASE_PASSWORD="password"
DATABASE_NAME="hogehoge_development"
```

動いたが、ローカルのMySQL無しでは動作しなかった。ローカルのMySQLクライアントに依存しているっぽいが、8.xと5.6を同居させたい場合、どちらを入れるか葛藤が招じるため微妙感ある。


### 5.7で統一する

８系でガラっと認証周りが変わったっぽく、５.6で作った環境を８系で動かすとかその逆とか無理っぽかった。
5.7なら両方とりあえず動きはした。無理矢理感。

### 5.6だけを入れる

```shell
rm -rf /usr/local/var/mysql
brew remove --force mysql
brew remove --force mysql@5.6
brew install mysql@5.6
mysql.server start
```
### docker-compose.yml書く

もう諦めて半端なことはせず、Railsもコンテナで動かして`docker compose`で繋いでやる。
最初が多少めんどいが、これが一番良さそう。WordPressでやったことあるし。
暇になったらやる。やったら追記する。

## 参考

- [brew services start mysql で mysql デーモンが起動しないと思ったら datadir が古かった](https://qiita.com/niwatako/items/6d79dd9b69443f4c021c)
- [Multiple MySQL Versions with Homebrew](https://gist.github.com/benlinton/d24471729ed6c2ace731)
- [homebrewで入れたmysqlを8系から5系にダウングレードする](https://qiita.com/dkjym/items/d2bfca70bc9b0c2ee9dc)