MySQLエラー解決法（Mac編）

[株式会社TECH LUCK](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)という会社で代表兼エンジニアをしている齊藤です。

DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい

また、Railsエンジニアも募集しておりますので、興味がありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご連絡いただけますと幸いです。

# 前提

Macでの開発ローカル環境にMySQLをインストールする際に、よくエラーが出てしまいます。
このような環境構築のMySQLのエラーを多く解決してきて、溜まった対処法や知見を共有します。
もし、MySQLのインストールでつまずいた時は、この記事を参考にしてみるといいかもしれません。
開発環境はMacOSでHomebrewを使ってMySQLをインストールしています。
途中、Ruby on Railsの開発の際のエラーもでてきますので、関係ない人は無視してください。

# MySQLのエラー対処

## rakeコマンドでのエラー

```bash:ターミナル
rake aborted!
LoadError: dlopen(/Users/user/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/extensions/x86_64-darwin-14/2.1.0-static/mysql2-0.3.18/mysql2/mysql2.bundle, 9): Library not loaded: /usr/local/lib/libmysqlclient.18.dylib
  Referenced from: /Users/user/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/extensions/x86_64-darwin-14/2.1.0-static/mysql2-0.3.18/mysql2/mysql2.bundle
  Reason: image not found - /Users/user/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/extensions/x86_64-darwin-14/2.1.0-static/mysql2-0.3.18/mysql2/mysql2.bundle
/Users/user/Desktop/myprojects/bijo/config/application.rb:7:in `<top (required)>'
/Users/user/Desktop/myprojects/bijo/Rakefile:4:in `<top (required)>'
(See full trace by running task with --trace)
```

このエラーは、`/usr/local/lib/libmysqlclient.18.dylib`というファイルがないことが原因でエラーになっています。
ですので、MySQLの本体の場所からシンボリックリンクを貼ると解決します。

```bash:ターミナル
sudo ln -s /usr/local/Cellar/mysql/5.6.25/lib/libmysqlclient.18.dylib  /usr/local/lib/libmysqlclient.18.dylib
```

## MySQLの自動起動設定の際のエラー
```bash:ターミナル
~/Library/LaunchAgents is not a directory
```
touchコマンドなどで、`~/Library/LaunchAgents` を作成して解決しました。（この方法でいいのかは不明。）
`LaunchAgents` とはログインしたユーザの権限で起動時にプログラムを実行するための機能です。
たまに管理するためのファイルがない場合がありますが、touchコマンドで作成しても正常に動きました。

## performance_schema関連のエラー
```bash:ターミナル
Mysql2::Error: Table 'performance_schema.session_variables' doesn't exist
```

これはMySQLをアップグレードすると直ることが多いようです。
上記は下記のコマンドで解決することが多かったです。

```bash:ターミナル
mysql_upgrade -u root -p --force
mysql.server restart
```

## MySQL5.7でのエラー
MySQL5.7ではパスワードが勝手に付与され、インストールした後に`mysql -u root`はアクセスしようとしても以下のようなエラーが出てくるという謎の問題がたまにあります。

```bash:ターミナル
Access denied for user 'root'@'localhost' (using password: NO)Please provide the root password for your MySQL installation
```

こうなってしまった場合は、MySQLをセーフモードで立ち上げてパスワードを初期化すれば直ることが多いです。

```bash:ターミナル
mysql.server stop
launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist 
ps aux | grep mysql
kill -9 <PID>
```

まず、セーフモードでMySQLを立ち上げます。

```bash:ターミナル
mysqld_safe --skip-grant-tables &
```

次に、MySQLにログインしてのuserテーブルのrootのパスワードを変更します。

```bash:ターミナル
use mysql;
update user set authentication_string=PASSWORD("") where User='root';
exit;
```

これで、rootのパスワードを無効にすることができました。
MySQLを正常モードで起動して、きちんとrootでログインすることができるか確認してみましょう。

```bash:ターミナル
mysql.server restart
mysql -u root
```

### MySQL5.7について
Mysql5.7では不具合がありエラーが起きることが多いそうです。
![MySQL5.7でのエラー](http://www.slideshare.net/yoku0825/mysql-57-51945745)

バージョン5.7は使わずに、他のバージョンを使うのも一つの解決策です。
![HomebrewでMySQLのバージョンを指定してインストール](https://gist.github.com/STAR-ZERO/5335577)

## brew install mysqlでのエラーの場合
MacOS El capitanで `brew install mysql` を実行すると下記のようなエラーが出ることがあります。

```bash:ターミナル
curl: (22) The requested URL returned error: 410 Gone
Trying a mirror...
==> Downloading http://tukaani.org/xz/xz-5.2.0.tar.gz

curl: (22) The requested URL returned error: 403 Forbidden
Error: Failed to download resource "xz"
Download failed: http://tukaani.org/xz/xz-5.2.0.tar.gz
```

原因として考えられるのが、homebrewが古いバージョンのものであることです。Homebrewをアップデートしてみましょう。

```bash:ターミナル
brew update
```

しかし、上記コマンドを実行しても下記のようなエラーが出てくることがありました。

```bash:ターミナル
error: unable to unlink old '.travis.yml' (Permission denied)
Error: Failure while executing: git pull --ff --no-rebase --quiet origin refs/heads/master:refs/remotes/origin/master
```

El capitanでは `usr/local` のディレクトリの所有者がrootになっていると動かないようで、所有権をユーザーに変更します。

```bash:ターミナル
sudo chown $(whoami):admin /usr/local
```

そこから再度、Homebrewをアップデートしますがまたエラーが出てきました。

```bash:ターミナル
Library/Formula/ratfor.rb already exists, no checkout
Library/Formula/sickrage.rb already exists, no checkout
Library/Formula/viennacl.rb already exists, no checkout
Library/Formula/viewvc.rb already exists, no checkout
Library/Formula/xxhash.rb already exists, no checkout
Could not restore untracked files from stash
Error: Failure while executing: git stash pop --quiet
```

これに関しては、以下の方法でHomebrewをアップデートしました。
それからMySQLのインストールを行いました。

```bash:ターミナル
cd $(brew --prefix)
git fetch
git reset --hard origin/master
cd ~/
brew update
```


## MySQLのプロセスがすでに動いている場合
`mysql.server start` を実行してMySQLを起動しようとしても、下記のようなエラーが出てくる場合があります。

```bash:ターミナル
ERROR! The server quit without updating PID file (/usr/local/var/mysql/user-no-MacBook-Air.local.pid).
```

このエラーは、mysql関連のプロセスがすでに起動しているというエラーですので、MySQLのプロセスを一度切りましょう。

```bash:ターミナル
ps aux | grep mysql  #MySQL関連のプロセス確認
```

プロセスの所有権がユーザ名でない場合は、以下のコマンドで強制的に終了。

```bash:ターミナル
kill -9 <PID>
```

これで違う所有権になっているプロセスを終了させてから、

```bash:ターミナル
mysql.server start
```

とすると動き出します。
これでも解決しない場合は下記のエラーを参照してください。


## MySQLの起動に関するファイルの権限が違う場合のエラー
サーバーが起動しない場合は、MySQL関連のファイルの所有権がユーザーになっていない可能性があります。
以下のコマンドでMySQL関連のファイルの所有権を確認しましょう。

```bash:ターミナル
ls -la /usr/local/var/mysql
```
このときにファイル所有権がユーザーになっていない場合は、以下のコマンドで所有権をユーザーに変更しましょう。

```bash:ターミナル
sudo chown ユーザー名 mysql /usr/local/var/mysql/~~~
```

このとき、すでにファイルの所有権がユーザーでないMySQLのプロセスが起動している場合があるため、すでに動いているMySQLのプロセスを切ってから起動させましょう。

```bash:ターミナル
ps aux | grep mysql
kill -9 PID
mysql.server start
```

## mysqlを以前にインストールしたことがある場合のエラー

```bash:ターミナル
mysql -u root
```

を実行してMySQLにログインしようとした際に、
`Access denied for user 'root'@'localhost' (using password: NO)`
のようなエラーがでました。
これは、以前のMySQLのデーモンが動いていてエラーを起こしている場合があります。
まずは、以下のコマンドを実行してデーモンを止めましょう。

```bash:ターミナル
launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
```

以前バージョンのMySQLを削除して、デーモンを再起動させましょう。
（やり方を忘れてしまったので、各自で検索していただければと思います。）
また、MySQLのデーモンをロードするには以下のコマンドを実行すれば元に戻ります。


```bash:ターミナル
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
```

## エラーログの確認
`/usr/local/var/mysql/[マシン名].local.err` がエラーを書き出してくれますので、tailコマンドでこのファイルの書き出しを常に見てみましょう。

```bash:ターミナル
tail -f /usr/local/var/mysql/[マシン名].local.err
```

このファイルに書き出されない場合は、`my.cnf`の設定を書き変えましょう。
`my.cnf` の設定は下記を参照してください。

## mysql.sockの場所がmy.cnfに記述されていないとき
色々やっても解決しない場合は、`my.cnf`を確認してみましょう。
`my.cnf` に `mysql.sock` の場所が書かれていないとエラーになってしまう場合があります。
ですので、mysql.sockの場所をmy.cnfに記述してあげると解決することがあります。
以下のmy.cnfの設定例を参考にしてみてください。

#### my.cnfの設定
```mysql:my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock

[mysql]
show-warnings
#safe-updates
prompt = '[\d] mysql> '

[mysqld]
# basic
datadir = /usr/local/var/mysql
#tmpdir = /tmp
port = 3306
socket = /tmp/mysql.sock
character-set-server = utf8
default-storage-engine = InnoDB
explicit_defaults_for_timestamp = 1
lower-case-table-names = 2

# max connections
max_connections = 64
# table_open_cache = max_connections * tables used in one transaction + 5
table_open_cache = 800
# table_definition_cache = all tables(50) + max_connections + 5
table_definition_cache = 400
# open_files_limit = table_open_cache * 1.4
open_files_limit = 1120

# global buffer
key_buffer_size = 16M
query_cache_type = 0
# innodb_buffer_pool_size = available memory for Mysql * 0.7
innodb_buffer_pool_size = 300M

# thread buffer
read_buffer_size = 256K
read_rnd_buffer_size = 512K
join_buffer_size = 256K
sort_buffer_size = 512K

# InnoDB
innodb_file_per_table
innodb_autoextend_increment = 64
innodb_log_files_in_group = 2
#innodb_log_group_home_dir = /tmp
innodb_log_file_size = 128M
innodb_log_buffer_size = 16M
innodb_flush_log_at_trx_commit = 1
innodb_flush_neighbors=0
#innodb_flush_method=O_DIRECT
innodb_thread_concurrency = 4
innodb_commit_concurrency = 4

# log
#log_output = /tmp
general_log = 0
slow_query_log = 0

[mysqldump]
#max_allowed_packet = 16M
quick
set-charset
tsingle-transaction
```

### `my.cnf` の場所
`my.cnf` を配置できる場所は複数あり、読み込む順序が決まっています。
読み込む順番は下記のようになっています。

1. ~/.my.cnf
2. /etc/my.cnf
3. /etc/mysql/my.cnf

配置場所は自由に決めてもよいですが、複数の場所に `my.cnf` を配置すると後から読み込まれたオプションの値が優先されます。


# MySQL関連の基本コマンド
基本的なMySQL関連のコマンドを載せておきます。
参考になれば幸いです。

```bash:ターミナル
mysql --version  #mysqlのバージョンを表示する

mysql --help  #mysqlについてのヘルプを表示する。my.cnfの場所も書かれている

brew info mysql  #mysqlの情報や注意書きが見れる

mysql.server status  #mysqlのサーバー状態を調べる

mysql.server start  #mysqlを起動させる

mysql.server stop  #mysqlを停止させる

mysqld start  #mysqldを起動させる
```

# まとめ
結構アバウトな感じになってしまっていますので、この記事だけではなく以下の記事なども参考にしてエラー対処してみてください。

# 参考URL
[mysqlのエラー対処法（その1）](http://easyramble.com/mysql-server-pid-file-error.html)
[mysqlのエラー対処法（その2）](http://takuyatsuji.com/archives/787)
[mysqlのdemonについて](
http://open-groove.net/mysql/mysql-start-stop/)
[my.cnfの設定例（その1）](http://krakenbeal.blogspot.jp/2012/04/machomebrewmysql.html)
[my.cnfの設定例（その2）](http://easyramble.com/example-of-mysql-options.html)
[my.cnfの設定例（その3）](
http://time-complexity.blogspot.jp/2013/10/mysqlmycnf.html)
[mysql.plistの自動起動設定](http://ikm.hatenablog.jp/entry/2013/10/11/115440)
[mysqlの設定の詳細](http://enterprisezine.jp/dbonline/detail/4116)
[mysql.sockが開けない時の対処法](http://krakenbeal.blogspot.jp/2014/10/homebrew-mysql-tmpmysqlsock.html)
[mysqlの詳細など](http://woshidan.hatenablog.com/entry/2014/12/29/152923)
[LaunchAgentsについて](http://www.sfc.itc.keio.ac.jp/ja/network_misc_bgtask_osx.html)