CentOS7.1にMySQL 5.7をインストール

今回CentOS7.1上に MySQL5.7をインストールしたので、その手順を備忘録としてまとめておきます。
構築した環境は以下の通りです。

# 環境
|OS/ミドルウェア|バージョン     |
|:------------|------------:|
| CentOS      |7.1          |
| MySQL       |5.7.12       |

# 1. MySQLリポジトリを追加し、MySQLをインストール

はじめに、CentOS 7.1にMySQLをインストールするために公式サイトからリポジトリ追加していきます。

```bash
$ sudo rpm -ivh http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
$ sudo yum install -y mysql-community-server
$ mysqld --version  # mysql server のバージョンを確認
mysqld  Ver 5.7.12 for Linux on x86_64 (MySQL Community Server (GPL))
$ mysql --version   # mysql client のバージョンを確認
mysql  Ver 14.14 Distrib 5.7.12, for Linux (x86_64) using  EditLine wrapper
```

# 2. MySQLの初期パスワードを確認

まず、MySQLを起動します。

```bash
$ sudo systemctl start mysqld.service
```

MySQL 5.7では、初回起動と同時にテンポラリの初期パスワードが生成されるため、MySQLのログファイルから初期パスワードを確認する必要があります。

```bash
$ # パスワードを空入力してログインすることができない
$ mysql -u root -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
```

* ログファイルから初期パスワードを確認

```bash
$ sudo cat /var/log/mysqld.log | grep 'temporary password'  # 初期パスワードを確認
2016-04-21T14:20:10.491632Z 1 [Note] A temporary password is generated for root@localhost: xeqaVmIrY4=e
```

今回の構築では、初期パスワードが **xeqaVmIrY4=e** と出力されたので、こちらをもとに手順３でMySQLの初期設定を行っていきます。

# 3. MySQLのセキュリティ設定

rootユーザのパスワードなどを変更するため、次のコマンドで以下の変更を行っていきます。

```bash
$ mysql_secure_installation

Securing the MySQL server deployment.

Enter password for user root:   # ここでログファイルから取得した初期パスワードを入力します。

The existing password for the user account root has expired. Please set a new password.

New password: # root ユーザの新規パスワードを入力します。

Re-enter new password: # 確認のためもう一度入力します。
```

* root ユーザのパスワードを設定。

```bash
The 'validate_password' plugin is installed on the server.
The subsequent steps will run with the existing configuration
of the plugin.
Using existing password for root.

Estimated strength of the password: 100 
Change the password for root ? ((Press y|Y for Yes, any other key for No) : y

New password: 

Re-enter new password: 

Estimated strength of the password: 100 
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.
```

* 匿名ユーザーアカウントを削除。

```bash
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y # 匿名ユーザーアカウントを削除。
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.
```

* ローカルホスト以外からアクセス可能な root アカウントを削除。

```bash
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y # ローカルホスト以外からアクセス可能な root アカウントを削除。
Success.

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.
```

* test データベースの削除

```bash
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y # test データベースの削除
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.

All done! 

```

# 4. MySQLにログインできるか確認

手順３で設定したパスワードでMySQLにログインできるか確認します。

```bash
$ mysql -u root -p
Enter password: # 設定したパスワード
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.12 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, 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
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> 
```

# 5. 設定ファイルの編集と起動設定

[こちらの記事](http://weblabo.oscasierra.net/mysql-57-init-setup/)同様に、サービス提供時に突然データベースにログインできなくなることを防ぐため、パスワードの有効期限を0に設定します。
また、デフォルトの文字コードもUTF-8にしておきます。

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

```conf:my.cnf
[mysqld]
・
・
・
character-set-server = utf8
default_password_lifetime = 0
```

最後に設定内容を反映させるためにMySQLを再起動し、次回の起動時以降自動で起動するように設定します。

* MySQLを再起動

```
$ sudo systemctl restart mysqld.service
```

* MySQLの自動起動設定

```bash
$ sudo systemctl enable mysqld.service
$ systemctl list-unit-files -t service | grep mysqld
mysqld.service                              enabled 
```

以上で設定は完了です。

# 補足
MySQL5.7では、デフォルトでSQLモードにONLY_FULL_GROUP_BYやNO_ZERO_IN_DATEなどが追加されているため、これらが影響する処理を行っていると正常に動作しなくなる場合があります。
※実際に私もWordPressの[HyperDBプラグイン](https://gagor.pl/2016/02/wordpress-with-hyperdb-on-php-7-0/)が正常に動作せずにハマりました。

```mysql
mysql> select @@global.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@global.sql_mode                                                                                                                         |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

```

そのような状態になるのを防ぐため、以下のようにmy.cnfに必要なSQLモードを記述しておくことを推奨します。

```conf:my.cnf
[mysqld]
・
・
・
sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' # ここに必要なSQLモードを記述
```

```bash
$ sudo systemctl restart mysqld.service
$ mysql -u root -p
Enter password: # 設定したパスワード
```
```mysql
mysql> select @@global.sql_mode;
+--------------------------------------------------------------------------------------------------------------+
| @@global.sql_mode                                                                                            |
+--------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+--------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)
```


# 参考文献
1. MySQL 5.7 を CentOS 7 に yum インストールする手順 _ WEB ARCH LABO, http://weblabo.oscasierra.net/installing-mysql57-centos7-yum/, Online: accessed 22-April-2016.
2. mysql_secure_installation の中身を追ってみた - Qiita, http://qiita.com/yoshi-naoyuki/items/d9b5655cdf77ca435faa, Online; accessed 22-April-2016.
3. MySQL __ MySQL 5.7 Reference Manual __ 5.4.4 mysql_secure_installation — Improve MySQL Installation Security, https://dev.mysql.com/doc/refman/5.7/en/mysql-secure-installation.html, Online; accessed 22-April-2016.
4. MySQL 5.7.8以降で古いアプリが動かない場合の対処（sql_mode） - Qiita, http://qiita.com/tao_s/items/fdd4fef22555207e1fb8, Online; accessed 22-April-2016.
5. MySQL5.6にしていくつかのSQLでエラーが出るようになった _ シーズクリエイターズブログ, http://www.seeds-std.co.jp/seedsblog/1035.html, Online; accessed 22-April-2016.