MacでHomebrewを使ってinstallしたMySQL5.6とMySQL5.7を切り替えて使う


## 背景
プロジェクトによってMySQLのバージョンを切り替えて使う場合に、Homebrewでインストールしたものを切り替えて使いたいと思いました。

普段RubyMineを使って開発しており、gemの`mysql2`が参照するlib（`libmysqlclient.20.dylib`や`libmysqlclient.18.dylib`）の参照エラーが出ないようにしたいというのが発端です。

## 切り替えのポイント
1. DBの設定やデータ（`/usr/local/var/mysql/`）は、それぞれのバージョン用のものを切り替えて使う
2. `brew unlink`と`brew link`を使ってアクティブなMySQLのバージョンを切り替える


## 手順
例として、MySQL5.7がインストールされていて、後からMySQL5.6をインストールすることを想定します。

#### 1. `/usr/local/var/mysql/`をrenameして退避しておきます。

設定やDBのデータが格納されているので、退避しておきます。

```bash
$ mv /usr/local/var/mysql /usr/local/var/mysql_57
```

#### 2. MySQL5.7用のシンボリックリンクを削除しておきます。
```bash
$ brew unlink mysql
```

このシンボリックリンクは
```/usr/local/bin/mysql -> ../Cellar/mysql/5.7.10/bin/mysql```
や
```/usr/local/lib/libmysqlclient.20.dylib -> ../Cellar/mysql/5.7.10/lib/libmysqlclient.20.dylib```
などのことを指します。

`brew unlink`でまとめて消してくれます。（便利ですね）

このシンボリックリンクが存在する状態で別のバージョンをインストールすると次のようなエラーが出てしまいます。

```bash
$ brew install mysql56
==> Reinstalling homebrew/versions/mysql56
==> Downloading https://homebrew.bintray.com/bottles-versions/mysql56-5.6.27.el_capitan.bottle.tar.gz
Already downloaded: /Library/Caches/Homebrew/mysql56-5.6.27.el_capitan.bottle.tar.gz
==> Pouring mysql56-5.6.27.el_capitan.bottle.tar.gz
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink bin/innochecksum
Target /usr/local/bin/innochecksum
is a symlink belonging to mysql. You can unlink it:
  brew unlink mysql

To force the link and overwrite all conflicting files:
  brew link --overwrite mysql56

To list all files that would be deleted:
  brew link --overwrite --dry-run mysql56
```

後からでも

```bash
$ brew unlink mysql && brew link mysql56
```
を実行することでリンクを貼り直すことはできますが、ログが大量に出てエラーに気づきにくいので、先にリンクを消しておく方が良いです。

#### 3. MySQL5.6をインストールします。

古いバージョンはバージョン名のついたパッケージになっています。
（バージョンなしのmysqlは現時点では5.7がインストールされます）

```bash
$ brew search mysql
```
を実行すると、

- mysql
- homebrew/versions/mysql51
- homebrew/versions/mysql55
- homebrew/versions/mysql56

といったものがリストに出てきます。
今回はMySQL5.6をインストールしたいのでmysql56を使います。

```bash
$ brew install mysql56
```

#### 4. MySQL5.6を起動してバージョンを確認します。

```bash
$ mysql.server start
Starting MySQL
.. SUCCESS!
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.27 Homebrew

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

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>
```
MySQL5.6が起動することを確認できました。

もしバージョンに5.7が表示されていた場合、シンボリックリンクの張替えができていない可能性があるのでログ等を確認しましょう。

#### 5. MySQL5.6を停止してデータを退避します。
```bash
$ mysql.server stop
Shutting down MySQL
. SUCCESS!
$ mv /usr/local/var/mysql /usr/local/var/mysql_56
```

#### 6. もともとインストールされていたMySQL5.7が起動することを確認します。

```bash
$ mv /usr/local/var/mysql_57 /usr/local/var/mysql
$ brew unlink mysql56 && brew link mysql
Unlinking /usr/local/Cellar/mysql56/5.6.27... 106 symlinks removed
Linking /usr/local/Cellar/mysql/5.7.10... 92 symlinks created
$ mysql.server start
Starting MySQL
. SUCCESS!
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.10 Homebrew

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

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>
```

MySQL5.7が起動することを確認できました。

## まとめ
ここまできて

- 起動中のMySQLを停止する
- 設定とデータディレクトリ（`/usr/local/var/mysql`）を切り替える
- `brew unlink`と`brew link`でアクティブなMySQLを切り替える
- MySQLを起動する

で切り替えられるようになりました。

毎回手で切り替えるのは大変なので、切り替え用のスクリプトを作っておくと良いかと思います。

### 参考: `/usr/local/var/mysql/`の切り替えが必要な理由
一度でも5.7を起動してしまうと、同じデータを使って5.6を起動すると次のようなエラーが出るようになります。

```bash
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/ogin.local.pid).
```

mysqld等は動いていなかったので権限周りと思われますが、うまく解決できませんでした。
（バージョンによってディレクトリ構成が違っていたので、権限以外にも何か影響しているのかもしれません）

#### MySQL5.6とMySQL5.7の初期のデータディレクトリ構成(`/usr/local/var/mysql/`)

```bash:MySQL5.6
drwxr-xr-x  10 ogi  admin       340  2 26 11:27 .
drwxr-xr-x  11 ogi  admin       374  2 26 11:27 ..
-rw-rw----   1 ogi  admin        56  2 26 11:27 auto.cnf
-rw-rw----   1 ogi  admin  50331648  2 26 11:27 ib_logfile0
-rw-rw----   1 ogi  admin  50331648  2 26 11:26 ib_logfile1
-rw-rw----   1 ogi  admin  12582912  2 26 11:27 ibdata1
drwx------  81 ogi  admin      2754  2 26 11:26 mysql
-rw-r-----   1 ogi  admin      6362  2 26 11:27 ogin.local.err
drwx------  55 ogi  admin      1870  2 26 11:26 performance_schema
drwx------   2 ogi  admin        68  2 26 11:26 test
```

```bash:MySQL5.7
drwxr-xr-x   18 ogi  admin       612  2 26 11:33 .
drwxr-xr-x   11 ogi  admin       374  2 26 11:33 ..
-rw-r-----    1 ogi  admin        56  2 26 11:33 auto.cnf
-rw-------    1 ogi  admin      1680  2 26 11:33 ca-key.pem
-rw-r--r--    1 ogi  admin      1075  2 26 11:33 ca.pem
-rw-r--r--    1 ogi  admin      1079  2 26 11:33 client-cert.pem
-rw-------    1 ogi  admin      1676  2 26 11:33 client-key.pem
-rw-r-----    1 ogi  admin       408  2 26 11:33 ib_buffer_pool
-rw-r-----    1 ogi  admin  50331648  2 26 11:33 ib_logfile0
-rw-r-----    1 ogi  admin  50331648  2 26 11:33 ib_logfile1
-rw-r-----    1 ogi  admin  12582912  2 26 11:33 ibdata1
drwxr-x---   77 ogi  admin      2618  2 26 11:33 mysql
drwxr-x---   90 ogi  admin      3060  2 26 11:33 performance_schema
-rw-------    1 ogi  admin      1680  2 26 11:33 private_key.pem
-rw-r--r--    1 ogi  admin       452  2 26 11:33 public_key.pem
-rw-r--r--    1 ogi  admin      1079  2 26 11:33 server-cert.pem
-rw-------    1 ogi  admin      1680  2 26 11:33 server-key.pem
drwxr-x---  108 ogi  admin      3672  2 26 11:33 sys
```