Vagrant Amazon Linux にMySQL5.7をインストールする

## 概要
Vagrantを利用してAmazon Linux上に MySQL をインストールします。

##環境
* Mac OS X Sierra 10.12.6
* Vagrant 2.0.0
* VirtualBox 5.1.30r118389
* MySQL 5.7

MacOS上にVagrantを使ってVirtualboxを立てその中に環境構築しています。
OSイメージはAmazon Linuxの[こちら](https://app.vagrantup.com/mvbcoding/boxes/awslinux "こちら")を利用。

## インストール手順
### MySQL公式のyumリポジトリの追加
```
$ sudo yum -y install https://dev.mysql.com/get/mysql57-community-release-el6-11.noarch.rpm
```

### パッケージの最新化（yumアップデート）

```
$ sudo yum -y update
```

### MySQL5.7のインストール

```
$ sudo yum -y install mysql-community-server
```

### バージョンの確認

```
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.21, for Linux (x86_64) using  EditLine wrapper
```

### MySQLを起動

```
$ sudo service mysqld start
```

### MySQLの自動起動設定
OSの再起動を行ってもMySQLサーバが自動起動する設定を行います。
`sudo su` でrootユーザーになり、以下のコマンドを実行します。

```
$ chkconfig mysqld on
```


### パスワードの変更
MySQL5.7からは初期パスワードがデフォルトで設定されているため、パスワードの変更を行います。

初期パスワードは以下の通り設定されています。`CfgsTahfi4)s`が初期パスワードです。

```
$ sudo cat /var/log/mysqld.log | grep 'temporary password'
2018-03-05T07:11:15.246568Z 1 [Note] A temporary password is generated for root@localhost: CfgsTahfi4)s
```

初回のセキュリティ設定の中で、パスワードの変更も行います。

```
$ mysql_secure_installation
```

下記の記事に、設定内容が詳しく記載されています。
[MySQL 5.7 をインストールしたら最初に行うセットアップ](https://weblabo.oscasierra.net/mysql-57-init-setup/)

### パスワードを使ってMySQLにログイン
上記で設定したパスワードを使ってログインします。

```
$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 5.7.21 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, 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>
```

### 設定ファイルの編集

```
$ vi /etc/my.cnf
```

以下の内容を追記します。


```
character-set-server=utf8mb4
collation-server=utf8mb4_bin
skip-character-set-client-handshake
default-storage-engine=InnoDB
innodb_file_per_table=1
innodb_large_prefix=1
innodb_file_format=Barracuda
innodb_default_row_format=DYNAMIC
default_password_lifetime = 0
slow_query_log = 1
long_query_time = 0.1
slow_query_log_file = /var/log/mysql-slow-query.log

[mysql]
auto-rehash
default-character-set = utf8mb4

[mysqldump]
default-character-set = utf8mb4
```

上記設定の詳細は以下の通りです。

#### 文字コードに関する設定
文字コードに関する設定は以下になります。

```
character-set-server=utf8mb4
collation-server=utf8mb4_bin
skip-character-set-client-handshake

[mysql]
default-character-set = utf8mb4

[mysqldump]
default-character-set = utf8mb4
```

MySQLでは、文字コードの設定はサーバ側の文字コードとクライアント側の文字コードの両方について考慮する必要があります。


 - character-set-server

MySQLサーバ側の文字コード設定です。
MySQLでは、クライアント文字コード、サーバ文字コードを別々に設定します。

 - collation-server

文字の照合順序（同じ文字(大文字、小文字など)のソート順のようなイメージ）の設定です。
MySQLでマルチバイト文字を扱うには考慮しておくべき問題があります。

絵文字の 🍣と🍺が同様のデータとして扱われてしまう「寿司ビール問題」
カタカナの「ハ」と「パ」が同じものとして扱われてしまう「ハハパパ問題」

現状、この2つを解決する設定は `collation-server=utf8mb4_bin` のみです。
ただし、 `a` と `A` についても別の文字として扱われるようになります。
（デフォルト設定だと同じ文字として扱われます）

 - skip-character-set-client-handshake

MySQLのクライアント側（接続側）が設定する文字コード設定を無効化する事が出来ます。
常にMySQLサーバ側の設定（ここでは `utf8mb4`）が設定されて欲しいのでこの設定を有効にします。

 - default-character-set

文字コードを `utf8mb4` に設定します。
`[mysql]` セクションはmysqlサーバーへの設定、 `[mysqldump]` セクションはバックアップコマンドへの設定の設定となります。


#### ストレージエンジンに関する設定

 - default-storage-engine

デフォルトストレージエンジンの設定です。
ストレージエンジンとはRDBMSの心臓部で、実データへのアクセス処理を主に行う機能部分です。

ストレージエンジンは複数の種類がありますが、`InnoDB` は、トランザクションを扱える唯一のエンジンです。
MySQL 5.7からは、 `InnoDB`　がデフォルトのストレートエンジンとして設定されています。

また、テーブル単位でストレートエンジンを指定することも可能です。
この場合テーブルの作成時に、ストレートエンジンを指定します。

 - innodb_file_per_table

ストレージエンジン `InnoDB` に関する設定の1つです。

`innodb_file_per_table` に '1' を設定するとテーブルごとに専用のテーブルスペースを作成されます。
有効に設定ことにより、テーブルを削除するときにテーブルスペースのディスクスペースを再利用できる利点があります。

 - innodb_large_prefix
 
ストレージエンジン `InnoDB` に関する設定の1つです。
767バイトを超えるカラムにインデックスを貼ることを可能にします。

 - innodb_file_format

ストレージエンジン `InnoDB` に関する設定の1つです。
MySQLのファイル形式を設定します。
圧縮機能が利用可能になる `Barracuda` へ変更します。

 - innodb_default_row_format

ストレージエンジン `InnoDB` に関する設定の1つです。
ここでは `DYNAMIC` を指定しています。圧縮機能は、無効です。
ちなみに圧縮機能が有効なのは `COMPRESSED` です。
`COMPRESSED` は、圧縮・展開の処理が行われるため、パフォーマンスが低下するというデメリットがあります。

また、テーブル単位の指定も可能です。
テーブル作成時に `ROW_FORMAT=COMPRESSED` を指定すれば圧縮機能を有効に出来ます。

詳しくは [こちらの記事](https://engineers.weddingpark.co.jp/?p=622) を参考にして下さい。

 - default_password_lifetime

デフォルト設定だと365日でパスワードを強制変更するようにMySQLからエラーが出るようになっています。
運用中にこのエラーが出るとサービスが止まってしまうのでこの設定を明示的に無効化しています。

※ MySQL 5.7.11からはデフォルトで0に設定が変更されたようなのでこの設定は不要ですが念の為記載しておきます。

 - slow_query_log

スロークエリを出力する設定です。
名前の通り時間がかかっているSQLをログとして出力する為の設定です。
SQL実行に　`long_query_time` 秒以上かかったSQLのログを出力します。

 - long_query_time

スロークエリのログを出力するための時間設定です、

個人的には厳し目の設定にしておくのが良いと考えます。
ここでは0.1秒を設定しています。

遅いSQLはそれだけサーバのリソースを消費し、ユーザー体験にも悪影響を与えるので厳し目に設定を行っておき常に監視しておくのが良いでしょう。

 - slow_query_log_file

スロークエリが出力されるファイルパスです。
ここでは `/var/log/mysql-slow-query.log` を設定しています。

スロークエリは `mysqldumpslow` というコマンドで集計する事が可能です。
詳しくは [こちらの記事](https://webmake.info/mysql%E3%81%AE%E3%82%B9%E3%83%AD%E3%83%BC%E3%82%AF%E3%82%A8%E3%83%AA%E3%83%AD%E3%82%B0%E3%82%92mysqldumpslow%E3%81%A7%E5%88%86%E6%9E%90%E3%81%99%E3%82%8B/) を参考にして下さい。

### MySQLを再起動

```
$ sudo service mysqld restart
```

### 文字コードの設定が反映されているか確認

以下の通りの実行結果になることを確認します。

```
mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)
```