Mac MySQL 8.0 再インストールする

Laravelの記事を書く際にお試し用の環境をローカルに作るのですが、MySQLのrootパスワードをよく忘れる問題とか再インストールしたくなるので手順をまとめました。

## 環境

- macOS Catalina 10.15.4
- Homebrew 2.2.14
- MySQL 8.0.19

## MySQLのアンインストール

```shell-session
$ brew uninstall mysql
```

不要なファイルを削除する。
もちろんデータベースの中身は全て削除されるのでご注意ください。

```shell-session
rm -rf /usr/local/Cellar/mysql*
rm -rf /usr/local/bin/mysql*
rm -rf /usr/local/var/mysql*
rm -rf /usr/local/etc/my.cnf
rm -rf /usr/local/share/mysql*
rm -rf /usr/local/opt/mysql*
```

### パーミッションエラーが発生する場合

```shell-session
$ sudo chown -R $(whoami):admin /usr/local/*
$ sudo chmod -R g+w /usr/local/*
```

## MySQLのインストール

```shell-session
$ brew install mysql

We've installed your MySQL database without a root password. To secure it run:
    mysql_secure_installation

MySQL is configured to only allow connections from localhost by default

To connect run:
    mysql -uroot

To have launchd start mysql now and restart at login:
  brew services start mysql
Or, if you don't want/need a background service you can just run:
  mysql.server start
```

## MySQLの初期設定

```shell-session
$ mysql_secure_installation

mysql_secure_installation: [ERROR] unknown variable 'prompt=\U [\d] \R:\m>\_'.

Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: [空Enter]

Please set the password for root here.

New password: [rootユーザーのパスワードを入力]
Re-enter new password: [rootユーザーのパスワードを再度入力]

[残りは全て y でokです]
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.

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.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : [y]

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.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : [y]

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

### 補足: エラーが発生する場合

```
Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock'
```

古いMySQLの余計なプロセスが残ってしまっている可能性があるので、古いプロセスをキルするか一旦パソコンを再起動すると良いかもです。

## MySQL設定ファイル

```
$ vim /usr/local/etc/my.cnf
```

```
anyone can access. This is also intended only for testing,
# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
mysqlx-bind-address = 127.0.0.1

# 以下、追記する
character_set_server = utf8mb4 # 文字コード
collation_server = utf8mb4_ja_0900_as_cs # 照合順序
```

- `utf8mb4_0900_ai_ci` MySQL8.0からの標準
  - `utf8mb4` utf8で、マルチバイトを4バイトとする文字コードになります。
  - `0900` Unicodeのバージョン 9.00
  - `ai` Accent Insensitiveの略称。アクセントの違いを無視する。
    - 「は」と「ぱ」は等しい文字として評価される。
  - `ci` Case Insensitiveの略称。大文字と小文字の違いを無視する。
    - 「あ」と「ぁ」は等しいと評価される。

## MySQL サーバー起動

```shell-session
$ mysql.server start
```

### 補足: エラーが発生する場合

```
ERROR! The server quit without updating PID file
```

古いMySQLの余計なプロセスが残ってしまっている可能性があるので、古いプロセスをキルするか一旦パソコンを再起動すると良いかもです。

## Macログイン時に自動起動

自動起動を有効化するコマンドです。
(デフォルトは無効です。)

```shell-session
$ brew services start mysql
```

自動起動を無効化したい場合は下記のコマンドです。

```shell-session
$ brew services stop mysql
```

## rootユーザーでMySQLロへグイン

```shell-session
$ mysql -uroot -p
```

初期設定で入力したパスワードでログインします。

## 文字コードの設定確認

```
> SHOW VARIABLES LIKE '%char%';
+--------------------------+------------------------------------------------------+
| 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/local/Cellar/mysql/8.0.19/share/mysql/charsets/ |
+--------------------------+------------------------------------------------------+
```

## 文字コードの照合順序の設定確認

```
> SHOW VARIABLES LIKE '%collation%';
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| collation_connection          | utf8mb4_0900_ai_ci    |
| collation_database            | utf8mb4_ja_0900_as_cs |
| collation_server              | utf8mb4_ja_0900_as_cs |
| default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci    |
+-------------------------------+-----------------------+
```

## MySQL データベース作成

例として `sample` データベースを作成してみます。

```shell-session
> CREATE DATABASE sample;
```

- https://dev.mysql.com/doc/refman/8.0/en/create-database.html

## MySQL ユーザー作成

- ユーザー名: `phper`
- パスワード: `secret`

```shell-session
> CREATE USER phper@'%' IDENTIFIED BY 'secret';
```

- https://dev.mysql.com/doc/refman/8.0/en/create-user.html

## MySQL ユーザーにデータベースを操作する権限を付与

```shell-session
> GRANT ALL PRIVILEGES on sample.* to phper@'%';
```

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

## MySQLデータベース一覧

```
> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sample             |
| sys                |
+--------------------+
```

`sample` データベースが追加されていることがわかります。

## MySQLユーザー一覧

```
> SELECT Host, User, plugin FROM mysql.user;
+-----------+------------------+-----------------------+
| Host      | User             | plugin                |
+-----------+------------------+-----------------------+
| %         | phper            | caching_sha2_password |
| localhost | mysql.infoschema | caching_sha2_password |
| localhost | mysql.session    | caching_sha2_password |
| localhost | mysql.sys        | caching_sha2_password |
| localhost | root             | caching_sha2_password |
+-----------+------------------+-----------------------+
```

`phper@%` ユーザーが作成されています。

## phperユーザーの権限確認

```
> show grants for 'phper'@'%';
+---------------------------------------------------+
| Grants for phper@%                                |
+---------------------------------------------------+
| GRANT USAGE ON *.* TO `phper`@`%`                 |
| GRANT ALL PRIVILEGES ON `sample`.* TO `phper`@`%` |
+---------------------------------------------------+
```

`phper@%` ユーザーに `sample` データベースの権限が付与されています。

## MySQLからログアウト

```shell-session
> exit
```

## phperユーザーでMySQLへログイン

```shell-session
$ mysql -uphper -psecret sample
```



## 関連記事

- [MySQL 8.0 初期設定](https://qiita.com/ucan-lab/items/c80fb8a880679fa20162)
- [Mac MySQL8.0 ERROR! MySQL server PID file could not be found!](https://qiita.com/ucan-lab/items/90d640d90e9500079e86)