CentOS 7 に MySQL Server 8 をインストールする

CentOS 7 に **MySQL Community Server 8.0** を yum でパッケージインストールする手順の解説。

[MySQL :: MySQL 8.0 Reference Manual :: 2.5.1 Installing MySQL on Linux Using the MySQL Yum Repository](https://dev.mysql.com/doc/refman/8.0/en/linux-installation-yum-repo.html)

MySQL 5.7 は「[MySQL 5.7 セットアップ手順と関連情報 - Qiita](https://qiita.com/bezeklik/items/3fb55bfb9b7c3447f03f)」を参照。

## 公式リポジトリの追加
```bash
yum install https://repo.mysql.com/mysql80-community-release-el7.rpm
```
公式の [MySQL Yum Repository](https://dev.mysql.com/downloads/repo/yum/) から環境に合った `mysql80-community-release` パッケージの URL を取得してインストールする。

:::note
**リポジトリのエイリアス**
https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm のリダイレクト先の https://repo.mysql.com/ を確認すると、 mysql80-community-release-el7.rpm が mysql80-community-release-el7-7.noarch.rpm と同じタイムスタンプになっており最終版のエイリアスになっていると推測されるので、そちらを指定した方が楽だろう。
:::

インストールすると `/etc/yum.repos.d/` に以下のファイルが配置される。

* `mysql-community.repo`
* `mysql-community-source.repo`

## MySQL Server のインスト−ル

### mysql-server
```bash
yum install mysql-server
```
パッケージ名に `mysql-server` を指定すると `mysql-community-server` パッケージにエイリアスされる。

依存関係で以下のパッケージがインストールされる。

* `mysql-community-libs`
* `mysql-community-libs-compat`
* `mysql-community-client`
*  `mysql-community-common`

デフォルトでインストールされている `mariadb-libs` パッケージは自動でアンインストールされるので事前に削除する必要はない。

### mysql-devel
```
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
```
`mysql_config` コマンドを利用したい時や gem `mysql2` を利用する場合は `mysql-devel` (`mysql-community-devel` パッケージにエイリアスされる) をインストールする必要がある。

## 認証方式の変更
デフォルトの認証方式は割と地雷になるので要注意。

### 認証方式の指定
```bash
echo 'default-authentication-plugin = mysql_native_password' >> /etc/my.cnf
```
認証方式を `mysql_native_password` に変更する。

`mysql.user` テーブルの `plugin` カラムに保存されてしまうので、先に変更指定しておく必要がある。

### 認証エラー
```
PHP Warning:  mysqli_real_connect(): (HY000/2054): The server requested authentication method unknown to the client
```
デフォルトの認証方式では PHP などの接続ライブラリ側で未対応のため上記のようなエラーが発生する。

## 初期化
初期化にはサービスを初回起動する方法と `mysqld` を `--initialize-insecure` オプションで起動する方法がある。前者は初期パスワードが自動生成される。
https://github.com/mysql/mysql-docker/blob/mysql-server/8.0/docker-entrypoint.sh

### サービスの起動と初期化
```bash
systemctl start mysqld
```
サービス名は `mysqld` で、最初の起動時にサーバーのデータディレクトリが空の場合、以下の処理が行われる。

* サーバーの初期化
* SSL 証明書とキーファイルをデータディレクトリに生成
* `validate_password` のインストールと有効化
* スーパーユーザーアカウント `'root'@'localhost` の作成
* スーパーユーザーの初期パスワードの自動生成

#### 初期パスワードの確認
```bash
grep 'temporary password' /var/log/mysqld.log
```
```:出力例
2019-06-01T00:00:00.000000Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: InitP@ssw0rd
```
前述の初期化で生成されたスーパーユーザーの初期パスワードはエラーログファイルに記録される。

## root パスワードの変更

### パスワードの生成
```bash
< /dev/urandom tr -dc 'A-Za-z0-9!$%&()*+,-./:;<=>?@[\]^_{|}~' | head -c 16; echo
```
記号は [Password special characters - OWASP](https://www.owasp.org/index.php/Password_special_characters) 参照。
運用上混乱を招きやすいため `"` `'` `` ` `` `#` は除外。

https://unix.stackexchange.com/questions/330331/problems-with-mysql-5-7-and-reset-root-password-when-use-mysql-config-editor/352072

### パスワードの変更
```bash
mysqladmin -u root -p$(grep 'password' /var/log/mysqld.log | awk '{print $13}') password
```
```
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.
```
`mysqladmin` でスーパーユーザーの初期パスワードを変更しようとすると `Warning` が表示される。
MySQL 8.0 から `mysqladmin password` コマンドの引数（新パスワード）を省略できるようになった。 

初期化で `validate_password` が有効化されるため、パスワードに指定する文字列は以下の要件を満たす必要がある。

* 1文字以上の大文字
* 1文字以上の小文字
* 1文字以上の数字
* 1文字以上の特殊文字
* 合計8文字以上

#### SQL 文でパスワードを変更する方法
```sql
ALTER USER USER() IDENTIFIED BY 'NewP@ssw0rd!';
```

## MySQL Configuration Utility
```bash
mysql_config_editor set --host=localhost --user=root --password
```
暗号化されたパスワードを `.mylogin.cnf` ファイルに保存して mysql や mysqladmin などの MySQL クライアントのパスワード入力を省略することができる。

https://dev.mysql.com/doc/refman/8.0/en/mysql-config-editor.html

## MySQL クライアントの設定

### オプションファイル
```bash
echo -e "[mysql]\npager = less -SFXin" > ~/.my.cnf
```
オプションファイル `~/.my.cnf` に MySQL クライアントのオプションをユーザー固有に設定できる。

### オプショングループ
[第33回　MySQLのオプションファイル my.cnfの豆知識［その2］：MySQL道普請便り｜gihyo.jp … 技術評論社](http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0033#sec1_h1)

| プログラム | オプショングループ |
|:--|:--|
| `mysql`       | `[client]`, `[mysql]` |
| `mysql_secure_installation` | `[client]`, `[mysql]`, `[mysql_secure_installation]` |
| `mysqladmin`  | `[client]`, `[mysqladmin]` |
| `mysqldump`   | `[client]`, `[mysqldump]` |
| `mysqlpump`   | `[client]`, `[mysql_dump]` |
| `mysqlcheck`  | `[client]`, `[mysqlcheck]` |
| `mysqlbinlog` | `[client]`, `[mysqlbinlog]` |
| `mysqlimport` | `[client]`, `[mysqlimport]` |
| `mysqlshow`   | `[client]`, `[mysqlshow]` |
| `mysqlslap`   | `[client]`, `[mysqlslap]` |
| `mysqltest`   | `[client]`, `[mysqltest]` |

## DB および DB ユーザーの作成

### DB の作成
```bash
mysqladmin create dbname
```

### DB ユーザーの作成
```sql
CREATE USER 'dbuser'@'localhost' IDENTIFIED BY 'P@ssw0rd';
```

### 権限の割り当て
```sql
GRANT ALL PRIVILEGES ON `dbname`.* TO 'dbuser'@'localhost';
```

## 設定の確認

### 自動起動設定の確認
```bash
systemctl is-enabled mysqld
```
```:出力例
enabled
```
インストール直後にサービスが自動起動される設定になっている。

### 文字コード設定の確認
```sql
SHOW GLOBAL VARIABLES LIKE 'character_set\_%';
```
```sql
SHOW VARIABLES LIKE 'character_set\_%';
```
`GLOBAL` を省略するとデフォルト値の `LOCAL` として指定される。

#### 各データベースの文字コード設定の確認
```sql
SELECT * FROM information_schema.SCHEMATA;
```

### タイムゾーンの確認
```sql
SELECT @@system_time_zone, @@global.time_zone, @@session.time_zone;
```
サーバー起動時にホストマシンのタイムゾーンで `system_time_zone` システム変数で設定しようとし、その後この値は変更しない。
通常、タイムゾーンは `TZ` 環境変数で指定される。

`time_zone` 変数は接続する各クライアントのタイムゾーンを初期化するために使用される。デフォルト値は `SYSTEM` で `system_time_zone` の値を使用することを意味する。

## MySQL プログラム群
https://dev.mysql.com/doc/refman/8.0/en/programs-overview.html

### MySQL サーバーおよびサーバースタートアッププログラム
|プログラム|説明|
|---|---|
|`mysqld`|MySQL サーバー|
|`mysqld_safe`|MySQL サーバースタートアップスクリプト|
|`mysql.server`|MySQL サーバースタートアップスクリプト|
|`mysqld_multi`|Manage Multiple MySQL Servers|

### MySQL インストール関連プログラム
|プログラム|説明|
|---|---|
|`comp_err`|Compile MySQL Error Message File|
|`mysql_secure_installation`|Improve MySQL Installation Security|
|`mysql_ssl_rsa_setup`|Create SSL/RSA Files|
|`mysql_tzinfo_to_sql`|Load the Time Zone Tables|
|`mysql_upgrade`|Check and Upgrade MySQL Tables|

### MySQL クライアントプログラム
|プログラム|説明|
|---|---|
|`mysql`|MySQL コマンドラインクライアント|
|`mysqladmin`|MySQL サーバー管理用クライアント|
|`mysqlcheck`|テーブル管理プログラム|
|[`mysqldump`](https://qiita.com/bezeklik/items/5893a6a9ddbab29042f8)|データベースバックアッププログラム|
|`mysqlimport`|データインポートプログラム|
|`mysqlpump`|データベースバックアッププログラム|
|`mysqlshow`|Display Database, Table, and Column Information|
|`mysqlslap`|Load Emulation Client|

### MySQL 管理およびユーティリティプログラム
|プログラム|説明|
|---|---|
|`ibd2sdi`|InnoDB Tablespace SDI Extraction Utility|
|`innochecksum`|Offline InnoDB File Checksum Utility|
|`myisam_ftdump`|Display Full-Text Index information|
|`myisamchk`|MyISAM Table-Maintenance Utility|
|`myisamlog`|Display MyISAM Log File Contents|
|`myisampack`|Generate Compressed, Read-Only MyISAM Tables|
|`mysql_config_editor`|MySQL Configuration Utility|
|`mysqlbinlog`|Utility for Processing Binary Log Files|
|`mysqldumpslow`|Summarize Slow Query Log Files|

### MySQL プログラム開発ユーティリティ
|プログラム|説明|
|---|---|
|`mysql_config`|Display Options for Compiling Clients|
|`my_print_defaults`|Display Options from Option Files|

### その他のプログラム
|プログラム|説明|
|---|---|
|`lz4_decompress`|Decompress mysqlpump LZ4-Compressed Output|
|`perror`|Display MySQL Error Message Information|
|`zlib_decompress`|Decompress mysqlpump ZLIB-Compressed Output|

## MySQL Utilities

> 2018年5月30日時点の [Oracle ライフタイムサポートポリシー](https://www.oracle.com/support/lifetime-support/)に基づき、 MySQL Utilities は Oracle Sustaining Support の対象となります。Utilities のいくつかの機能は Shell のロードマップにあるので、ユーザーは MySQL Shell への移行をお勧めします。 [^mysql-utilities]

[^mysql-utilities]: ["Per Oracle's Lifetime Support policy, as of May 30, 2018, MySQL Utilities is covered under Oracle Sustaining Support. Some features of Utilities are on the roadmap for Shell, users are encouraged to migrate to MySQL Shell." - MySQL :: Download MySQL Utilities (Archived Versions) ](https://downloads.mysql.com/archives/utilities/)

### MySQL Utilities のインストール
```bash
yum install mysql-utilities
```
2017年1月18日リリースの MySQL Utilities 1.6.5 がインストールされる。

https://github.com/mysql/mysql-utilities

### コマンド一覧
|コマンド|備考|
|---|---|
|`mysqlauditadmin`||
|`mysqlauditgrep`||
|`mysqlbinlogmove`||
|`mysqlbinlogpurge`||
|`mysqlbinlogrotate`||
|`mysqldbcompare`||
|`mysqldbcopy`||
|`mysqldbexport`||
|`mysqldbimport`||
|`mysqldiff`||
|`mysqldiskusage`||
|`mysqlfailover`||
|`mysqlfrm`||
|`mysqlgrants`||
|`mysqlindexcheck`||
|`mysqlmetagrep`||
|`mysqlprocgrep`||
|`mysqlreplicate`||
|`mysqlrpladmin`||
|`mysqlrplcheck`||
|`mysqlrplms`||
|`mysqlrplshow`||
|`mysqlrplsync`||
|`mysqlserverclone`||
|`mysqlserverinfo`||
|`mysqlslavetrx`||
|`mysqluc`||
|`mysqluserclone`||

## MySQL Shell
https://dev.mysql.com/doc/mysql-shell/8.0/en/

### MySQL Shell のインストール
```bash
yum install mysql-shell
```