Linuxで複数のMySQLインスタンスを実行するまで

# 概要
1つのLinuxサーバーで複数のMySQLインスタンスを実行する際に、既存の記事通りではうまくいかなかったため記事化。
原因はMySQL 8.0からデフォルトで有効になったX protocolのポート指定をしていないため、他インスタンスのものと競合が起こっていたこと。

> 参考：
> [CentOS 7 + MySQL 5.7で複数のMySQLインスタンスを起動する #centos7 - Qiita](https://qiita.com/tomgoodsun/items/3a635559215eb1c4d9dc)
> [mysql 8.0 複数インスタンス @ CentOS7 + systemctl #centos7 - Qiita](https://qiita.com/piroyon/items/4bc0daa5b8591f6733ab)
> [【MySQL】【Linux】 MySQL を複数インスタンスで起動させる ～ Linux編 ～ - プログラム の超個人的なメモ](https://dk521123.hatenablog.com/entry/36493945)
# 手順
## 前提
- MySQLのバージョンは5.7系と8.0系がありますが、今回は**ver8.0.38**を使用します。
	- MySQLの5.7系を使用する際は、後述のX protocolがデフォルトで無効なので既存記事の通りで特に問題にならないはずです。
- LinuxのディストリビューションはUbuntu-20.04を使用します。

## 手順
### 1. MySQLのインストール
ここは既に他に詳しい記事がたくさんあるので省略します。
> 参考：[WSL2でMySQL serverを立ち上げてローカルネットワーク上の他のデバイスから接続するまで #初心者 - Qiita](https://qiita.com/haravity/items/63a62506c55c2969604e)

### 2. データディレクトリと設定ファイルの準備
ここがこの記事のミソなのですが、X protocolと呼ばれるクライアントプロトコルがポート33060を使用するので、新しい環境では以下のどちらかの手段を取らないと、ポートの競合が起きてソケットエラーにつながってしまいます。

- X protocolを使わない(方法1)
- 明示的にX protocolのポートを指定する(方法2)

> 参考：
> X protocolについて [MySQL X Protocol を解析してみる - tmtms のメモ](https://blog.tmtms.net/entry/2016/07/18/mysql-x-protocol)
> ソケットエラー [sockets - UbuntuでMySQLに接続できない問題： "Can't find mysqld.sock" エラーの解決策](https://sql-jp.dev/articles/254534134)

以下に2つの方法の手順を示します。
#### 方法 1: `mysqlx` プラグインを無効化する場合

##### データディレクトリの作成

```bash
sudo mkdir /var/lib/mysql-sbx
sudo chown -R mysql:mysql /var/lib/mysql-sbx
```

##### 設定ファイルの作成

`mysqlx` プラグインを無効にするための設定を含めたインスタンス用の設定ファイルを `/etc/mysql/` に作成し、以下の内容を記入します。

```bash
sudo nano /etc/mysql/my_sbx.cnf
```

```my_sbx.cnf
[mysqld]
datadir=/var/lib/mysql-sbx
socket=/var/run/mysqld/mysqld-sbx.sock
port=3307
mysqlx=OFF
```

::: note 
今回はポート3307を使用しますが、使用していないポートであれば何を使っても構いません。

ポートの確認は以下のコマンドで行えます。
```bash
sudo lsof -i:ポート番号
```
:::

#### 方法 2: `mysqlx` プラグインのポートとソケットを変更する場合

##### データディレクトリの作成

```bash
sudo mkdir /var/lib/mysql-sbx
sudo chown -R mysql:mysql /var/lib/mysql-sbx
```

##### 設定ファイルの作成

`mysqlx` プラグインのポートとソケットを明示的に設定するための設定ファイルを `/etc/mysql/` に作成し、以下の内容を記入します。


```bash
sudo nano /etc/mysql/my_sbx.cnf
```

```my_sbx.cnf
[mysqld]
datadir=/var/lib/mysql-sbx
socket=/var/run/mysqld/mysqld-sbx.sock
port=3307
[mysqlx]
mysqlx_port=33061
mysqlx_socket=/var/run/mysqld/mysqlx-sbx.sock
```

方法1と同様、空いているポートであれば33061以外でも構いません。

### 3. MySQLデータディレクトリの初期化

データディレクトリを初期化します。

```bash
sudo mysqld --initialize-insecure --user=mysql --datadir=/var/lib/mysql-sbx
```

### 4. systemdのサービスユニットファイルの作成

インスタンス用のサービスファイルを `/etc/systemd/system/` に作成します。

```bash
sudo nano /etc/systemd/system/mysql-sbx.service
```

```mysql-sbx.service
[Unit]
Description=MySQL Sandbox Instance
After=network.target

[Service]
User=mysql
Group=mysql
ExecStart=/usr/sbin/mysqld --defaults-file=/etc/mysql/my_sbx.cnf
PIDFile=/var/run/mysqld/mysqld-sbx.pid
Restart=always

[Install]
WantedBy=multi-user.target
```

### 5. サービスの有効化と起動

インスタンスを有効化し、起動します。
```bash
sudo systemctl enable mysql-sbx
sudo systemctl start mysql-sbx
```

以下のコマンドで、サーバーがactiveになっており、エラーが出ていないことを確認します。
```bash
sudo systemctl status mysql-sbx
```

### 6. サーバーへの接続確認
インスタンスに接続し、動作確認を行います。
パスワードは空白で問題ありません。

```bash
mysql -u root -p --socket=/var/run/mysqld/mysqld-sbx.sock
```

:::note warn

--initialize-insecureオプションを使用したため、ルートユーザーのパスワードが空白のままです。
下記の記事などを参考に、パスワードを追加しましょう。
> [MySQL 8 (MariaDB 10)のrootパスワード変更方法 | ポケブロ](https://blog.pokechoi.com/archives/1105#:~:text=%24%20mysql%20-u%20root%20%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%A7%E3%81%8D%E3%81%9F%E3%82%89%E3%80%81%E4%BB%A5%E4%B8%8B%E3%81%AE%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%80%81%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%81%AE%E5%86%8D%E8%A8%AD%E5%AE%9A%E3%82%92%E8%A1%8C%E3%81%84%E3%81%BE%E3%81%99%E3%80%82%20%3E%20ALTER%20USER,IDENTIFIED%20BY%20%27%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%27%3B%20%E8%A8%AD%E5%AE%9A%E3%82%92%E5%8F%8D%E6%98%A0%E3%81%95%E3%81%9B%E3%81%BE%E3%81%99%E3%80%82%20%3E%20FLUSH%20PRIVILEGES%3B%20%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%81%AE%E5%A4%89%E6%9B%B4%E3%81%AF%E3%81%93%E3%81%93%E3%81%A7%E5%AE%8C%E4%BA%86%E3%81%A7%E3%81%99%E3%80%82)
:::

新しいインスタンスに接続完了し、ルートユーザーのパスワードを変更すれば完了です。