[OCI] MySQLデータベースサービス(MDS) の高可用性機能(HA)を試してみる

# はじめに

MySQL も、データベースも素人ですが、前回 MySQLデータベースサービスを初めて使ってみたので、続いて MySQLデータベースサービス の高可用性（HA: High Availability）機能についても試してみることにしました。
[[OCI] MySQL Database Service(MDS) を初めて使ってみる](https://qiita.com/cocotaro0202/items/d21d9e361a62c9f17b1c)

# MySQLデータベースサービスの高可用性（MDS HA）
MDS HA は、2021/3/31 にリリースされました。
[MySQL Database Service High Availability](https://docs.oracle.com/en-us/iaas/releasenotes/changes/c6a50d3b-7420-48e0-92bd-49c717381ce3/)

#### 主な特長

- HA対応のMDSは**3つのMySQLインスタンスから構成され、各インスタンスは異なるAvailability Domain(可用性ドメイン)または Fault Domain(フォルトドメイン) にデプロイされます。**１つのプライマリインスタンスと２つのセカンダリインスタンスで構成されます。
- データは MySQLグループレプリケーションを使用して複製され、**プライマリに書き込まれるすべてのデータはセカンダリにも書き込まれます。**
- プライマリに障害が発生した場合、セカンダリの1つが自動的にプライマリに昇格し読み取り/書き込みモードに設定され、**データを失うことなく**クライアントアプリケーションの可用性を再開。これは**フェイルオーバー**と呼ばれます。
- 手動で切り替えて、セカンダリをプライマリに昇格させることもできます。これは**スイッチオーバー**と呼ばれます。

MDS HA の詳細はこちらもご覧ください。
[High Availability](https://docs.oracle.com/en-us/iaas/mysql-database/doc/business-continuity.html#MYAAS-GUID-2CD8BFB9-30B2-4ED5-BE27-E526DD3F6E0A)
![image-20210830110855727.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/9aae8e3a-bf99-230b-2249-58738778e304.png)
今回は手動のスイッチオーバーについて動作確認します。

# お試し環境
- リージョンは国内(大阪リージョン)を選択。そのため３つのMySQLインスタンスは３つの異なるフォルトドメインにデプロイされます。
- MDSはOCIのプライベート・サブネットに構築します。
- MDSへはパブリック・サブネットの踏み台サーバーから接続を試みます。踏み台サーバーは既に構成済みのものを使用します。
- 仮想クラウド・ネットワーク(VCN)も既存設定済みのものを使用します。
- MDSのためのセキュリティリストは設定済みです。
- 踏み台サーバーにMySQLクライアントがインストール済みです。
  セキュリティリストの設定、MySQLクライアントのインストールについては、[はじめに]章の記事をご覧ください。
![image-20210824150401081.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/c9532c30-f0c3-12d9-c5f3-39f3ea6fe035.png)

# 1. MDS HA の作成

OCIにサインイン後、左上のナビゲーションメニューから[データベース]-[MySQL]を選択し、**MySQL DBシステムの作成** をクリックします。
![image-20210824160859617.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/9140effc-df6b-0121-d08d-bf61ac584f18.png)
![image-20210824161013061.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/ce009504-67f4-cde2-9415-3438152941aa.png)
作成に必要な情報を入力していきます。
![image-20210824161243205.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/3c05d67e-a82f-f3bb-42fa-aab7ea3bd593.png)
**[コンパートメントに作成]** 任意のコンパートメントを指定します。
**[名前]** 任意の名前を指定します。例）mds-ha01
**[高可用性]** 高可用性を選択します。
![image-20210830155629442.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/3c7c0609-0704-4f48-09d9-c573f591f21a.png)
管理者資格証明の作成
**[ユーザー名]** root とします。
**[パスワード]** 任意のパスワードを指定します。
ネットワーキングの構成
**[仮想クラウド・ネットワーク]** 既存の仮想クラウド・ネットワークを選択。例）osaka-vcn
**[サブネット]** プライベート・サブネットを選択します。
![image-20210824162151892.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/c506b58e-da56-b7ec-c106-8db80b880e47.png)
優先プライマリの配置の構成
**[可用性ドメインの選択]** AD-1 のまま。
**[フォルト・ドメインの選択]** チェックを入れて、FAULT-DAMAIN-1 を選択します。
ハードウェアの構成
**[シェイプの選択]** 希望するシェイプに変更します。VM.Standard.E3.1.16GB を選択しました。
**[データ・ストレージ・サイズ(GB)]** デフォルト値：50 のままとします。 
![image-20210824162251629.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/1d155927-9676-4369-b6d5-5d3c6f06e643.png)
バックアップ・プランの構成
**[自動バックアップの有効化]** 有効化のまま。他の設定もデフォルトのままとします。
**作成** ボタンをクリックして、MDSを作成します。

正確に計測はしていませんが、約１５分程でMDS HA が作成されました。
![image-20210824164234969.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/b0240dbf-6d25-ce1a-a3d6-fd7bd26e0bc7.png)
**MySQL DBシステム情報** の以下項目を見ると、高可用性が構築されていることがわかります。
[DBシステム情報]
OCPU数:1 / MySQLインスタンス(**合計3**)
メモリー:16 GB / MySQLインスタンス(**合計48 GB**)
ストレージ・サイズ:50 GB / MySQLインスタンス(**合計150 GB**)
※合計値に３台分のインスタンス情報が記載されている

[高可用性]
高可用性:**有効**

[エンドポイント]
優先可用性ドメイン: TGjA:AP-OSAKA-1-AD-1
優先フォルト・ドメイン:**FAULT-DOMAIN-1**
※プライマリはFAULT-DOMAIN-1のMySQLインスタンス

ページ左下のリソースにて、**エンドポイント**をクリックして、作成されたMDSのエンドポイントを確認しておきます。後段のMDSへの接続に使用します。
![image-20210824164441905.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/e8753546-aa34-0b64-855b-c87c9fe3e9c3.png)

# MDS HA への接続確認

#### 前提
- MDSのためのセキュリティリストは設定済みです。
- 踏み台サーバーにMySQLクライアントがインストール済みです。
  セキュリティリストの設定、MySQLクライアントのインストールについては、[はじめに]章の記事をご覧ください。

踏み台サーバーからMDSへの接続を試みます。MDSを作成した時のユーザー名、エンドポイントのIPアドレスを指定します。

- ユーザー名：root
- エンドポイントのIPアドレス：例）192.168.100.125

```
mysql -u root -p -h 192.168.100.125
```

MDS作成時に指定したパスワードを入力し、その後 mysql プロンプトが表示され、無事MDSへの接続に成功することができました。

```
[opc@bastion01 ~]$ mysql -u root -p -h 192.168.100.125
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 72
Server version: 8.0.26-u1-cloud MySQL Enterprise - Cloud

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

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

# データの準備
サンプルデータベースも準備してSQLを実行したいのでMySQL Developer Zoneで公開されているExample Databaseの中でデータ量(約160MB)が多いemployeeデータベースを利用します。

employeeデータベースの導入方法については、巻末の参考URL - [その10 - MySQLで高速分析を体験する] - "5.サンプルデータベースの構築" をご覧ください。



サンプルデータ投入後データベース一覧を参照すると、サンプルデータベース(employees)が投入されたことが確認できました。続けて、employeesデータベースに切替えてテーブルを参照します。

```
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| employees          |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use employees;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------------+
| Tables_in_employees  |
+----------------------+
| current_dept_emp     |
| departments          |
| dept_emp             |
| dept_emp_latest_date |
| dept_manager         |
| employees            |
| salaries             |
| titles               |
+----------------------+
8 rows in set (0.00 sec)
```

SELECT 文を発行してemployeesテーブルを一覧表示すると約30万行の従業員データが格納されていることが確認できます。

```
mysql> select * from employees;
～略～
| 499991 | 1962-02-26 | Pohua          | Sichman          | F      | 1989-01-12 |
| 499992 | 1960-10-12 | Siamak         | Salverda         | F      | 1987-05-10 |
| 499993 | 1963-06-04 | DeForest       | Mullainathan     | M      | 1997-04-07 |
| 499994 | 1952-02-26 | Navin          | Argence          | F      | 1990-04-24 |
| 499995 | 1958-09-24 | Dekang         | Lichtner         | F      | 1993-01-12 |
| 499996 | 1953-03-07 | Zito           | Baaz             | M      | 1990-09-27 |
| 499997 | 1961-08-03 | Berhard        | Lenart           | M      | 1986-04-21 |
| 499998 | 1956-09-05 | Patricia       | Breugel          | M      | 1993-10-13 |
| 499999 | 1958-05-01 | Sachin         | Tsukuda          | M      | 1997-11-30 |
+--------+------------+----------------+------------------+--------+------------+
300024 rows in set (0.24 sec)
```

# MDS HA を検証してみる

## スイッチオーバー
MDS HA構築時の初期状態の FAULT-DOMAIN-1(FD1) プライマリからセカンダリへスイッチオーバーして動作の確認をおこないます。

### 1. 初期状態(FD1 がプライマリ)
以下のレプリケーション・グループ・メンバーの情報を取得して、プライマリ/セカンダリの構成を確認できます。

- ３行目がプライマリ：(MEMBER_HOST: fpkix1jubg9jfr8e)
- 他の２つがセカンダリ：(MEMBER_HOST: ugpws32d7l12xskt、MEMBER_HOST: caxcj3nadcfnv1ui)
  


```
mysql> SELECT * FROM performance_schema.replication_group_members\G;
*************************** 1. row ***************************
  CHANNEL_NAME: group_replication_applier
     MEMBER_ID: 4a9f2acb-04ad-11ec-a830-02001700f317
   MEMBER_HOST: ugpws32d7l12xskt
   MEMBER_PORT: 3306
  MEMBER_STATE: ONLINE
   MEMBER_ROLE: SECONDARY
MEMBER_VERSION: 8.0.26
*************************** 2. row ***************************
  CHANNEL_NAME: group_replication_applier
     MEMBER_ID: 5b1f67a6-04ad-11ec-a749-02001700fc8a
   MEMBER_HOST: caxcj3nadcfnv1ui
   MEMBER_PORT: 3306
  MEMBER_STATE: ONLINE
   MEMBER_ROLE: SECONDARY
MEMBER_VERSION: 8.0.26
*************************** 3. row ***************************
  CHANNEL_NAME: group_replication_applier
     MEMBER_ID: fd187dfa-04ac-11ec-a318-02001700a216
   MEMBER_HOST: fpkix1jubg9jfr8e
   MEMBER_PORT: 3306
  MEMBER_STATE: ONLINE
   MEMBER_ROLE: PRIMARY
MEMBER_VERSION: 8.0.26
3 rows in set (0.00 sec)
```

### 2. FD2 へスイッチオーバー
**[他のアクション]**-**[スイッチオーバー]**を選択して、FAULT-DOMAIN-2(FD2)へスイッチオーバーを実行してみます。 
![image-20210824171438311.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/f3f2ff86-f743-2bbd-01b3-75adcc860e4f.png)
**[FD-2]** を選択し、**スイッチオーバー** を実行します。
![image-20210824171703850.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/1ef925ea-04ec-2fb6-4c10-f267fb8fc361.png)
**スイッチオーバー**を更新中。。
![image-20210824171838344.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/27a7085b-d981-80eb-f628-bda02a921b80.png)
employeesデータベース(約160MB)を含むMDSが、約５分でFD2へスイッチオーバーされました。
![image-20210824172425065.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/1f06fab1-9b39-658f-83fa-213821664d9a.png)
**優先フォルト・ドメイン** は、**FAULT-DOMAIN-2** へ更新されています。

スイッチオーバー後に接続中のMySQLクライアントから再度SQLをリクエストすると、接続が切断された旨のERRORメッセージが表示されるので、再接続は必要です。

```
mysql> select * from employees;
ERROR 2013 (HY000): Lost connection to MySQL server during query 
```

再度MDSへ接続後、レプリケーション・グループ・メンバーの情報を取得します。今度は、

- １行目がプライマリ：(MEMBER_HOST: ugpws32d7l12xskt)

- 他の２つがセカンダリ：(MEMBER_HOST: caxcj3nadcfnv1ui、MEMBER_HOST: fpkix1jubg9jfr8e)

  に切り替わっていることが確認できます。

```
mysql> SELECT * FROM performance_schema.replication_group_members\G;
*************************** 1. row ***************************
  CHANNEL_NAME: group_replication_applier
     MEMBER_ID: 4a9f2acb-04ad-11ec-a830-02001700f317
   MEMBER_HOST: ugpws32d7l12xskt
   MEMBER_PORT: 3306
  MEMBER_STATE: ONLINE
   MEMBER_ROLE: PRIMARY
MEMBER_VERSION: 8.0.26
*************************** 2. row ***************************
  CHANNEL_NAME: group_replication_applier
     MEMBER_ID: 5b1f67a6-04ad-11ec-a749-02001700fc8a
   MEMBER_HOST: caxcj3nadcfnv1ui
   MEMBER_PORT: 3306
  MEMBER_STATE: ONLINE
   MEMBER_ROLE: SECONDARY
MEMBER_VERSION: 8.0.26
*************************** 3. row ***************************
  CHANNEL_NAME: group_replication_applier
     MEMBER_ID: fd187dfa-04ac-11ec-a318-02001700a216
   MEMBER_HOST: fpkix1jubg9jfr8e
   MEMBER_PORT: 3306
  MEMBER_STATE: ONLINE
   MEMBER_ROLE: SECONDARY
MEMBER_VERSION: 8.0.26
3 rows in set (0.00 sec) 
```

SQLを実行してみます。スイッチオーバー前と同じデータが表示されデータもちゃんと反映されてました。

```
mysql> select * from employees;
～略～
| 499990 | 1963-11-03 | Khaled         | Kohling          | M      | 1985-10-10 |
| 499991 | 1962-02-26 | Pohua          | Sichman          | F      | 1989-01-12 |
| 499992 | 1960-10-12 | Siamak         | Salverda         | F      | 1987-05-10 |
| 499993 | 1963-06-04 | DeForest       | Mullainathan     | M      | 1997-04-07 |
| 499994 | 1952-02-26 | Navin          | Argence          | F      | 1990-04-24 |
| 499995 | 1958-09-24 | Dekang         | Lichtner         | F      | 1993-01-12 |
| 499996 | 1953-03-07 | Zito           | Baaz             | M      | 1990-09-27 |
| 499997 | 1961-08-03 | Berhard        | Lenart           | M      | 1986-04-21 |
| 499998 | 1956-09-05 | Patricia       | Breugel          | M      | 1993-10-13 |
| 499999 | 1958-05-01 | Sachin         | Tsukuda          | M      | 1997-11-30 |
+--------+------------+----------------+------------------+--------+------------+
300024 rows in set (0.27 sec)
```

### 3. FD１へスイッチオーバー(戻し)
employeesテーブルに１行データを追加して、FAULT-DOMAIN-1(FD1)へMDSを再スイッチオーバーしてみます。従業員番号 500000 の従業員を追加します。

```
mysql> insert into employees values (500000, '1984-01-01', 'Koichi', 'Yamada', 'M', '2021-08-25');
Query OK, 1 row affected (0.01 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
```

最終行に１行追加されました。この状態でFD1 へスイッチオーバーして切り戻しをおこないます。

```
mysql> select * from employees;
～略～
| 499992 | 1960-10-12 | Siamak         | Salverda         | F      | 1987-05-10 |
| 499993 | 1963-06-04 | DeForest       | Mullainathan     | M      | 1997-04-07 |
| 499994 | 1952-02-26 | Navin          | Argence          | F      | 1990-04-24 |
| 499995 | 1958-09-24 | Dekang         | Lichtner         | F      | 1993-01-12 |
| 499996 | 1953-03-07 | Zito           | Baaz             | M      | 1990-09-27 |
| 499997 | 1961-08-03 | Berhard        | Lenart           | M      | 1986-04-21 |
| 499998 | 1956-09-05 | Patricia       | Breugel          | M      | 1993-10-13 |
| 499999 | 1958-05-01 | Sachin         | Tsukuda          | M      | 1997-11-30 |
| 500000 | 1984-01-01 | Koichi         | Yamada           | M      | 2021-08-25 |
+--------+------------+----------------+------------------+--------+------------+
300025 rows in set (0.23 sec)
```

FD1へのスイッチオバーが完了して、**優先フォルト・ドメイン** が**FAULT-DOMAIN-1** へ切り戻されました。
![image-20210827162636796.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496842/e8399861-823f-9679-67cc-d7ba0dd28f2d.png)
再接続して、追加されたデータが反映されているかを確認します。従業員番号 500000 の従業員も表示されてスイッチオーバー後にデータが反映されていることが確認できました。

```
mysql> select * from employees;
～略～
| 499993 | 1963-06-04 | DeForest       | Mullainathan     | M      | 1997-04-07 |
| 499994 | 1952-02-26 | Navin          | Argence          | F      | 1990-04-24 |
| 499995 | 1958-09-24 | Dekang         | Lichtner         | F      | 1993-01-12 |
| 499996 | 1953-03-07 | Zito           | Baaz             | M      | 1990-09-27 |
| 499997 | 1961-08-03 | Berhard        | Lenart           | M      | 1986-04-21 |
| 499998 | 1956-09-05 | Patricia       | Breugel          | M      | 1993-10-13 |
| 499999 | 1958-05-01 | Sachin         | Tsukuda          | M      | 1997-11-30 |
| 500000 | 1984-01-01 | Koichi         | Yamada           | M      | 2021-08-25 |
+--------+------------+----------------+------------------+--------+------------+
300025 rows in set (0.30 sec)
```

MDS HA を作成してスイッチオーバーの操作とデータの継続性を確認できました。
一般的には可用性構成を構築するのは複雑で小難しそうに思えますが、MDS HA はPaaSサービスなので単体のMDS のときと同様に簡単に可用性構成を実現できるのはいいですね。


# 参考URL
[その10 - MySQLで高速分析を体験する](https://oracle-japan.github.io/ocitutorials/beginners/creating-HeatWave/)
[書籍：15時間でわかるMySQL集中講座](https://www.amazon.co.jp/15%E6%99%82%E9%96%93%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8B-MySQL%E9%9B%86%E4%B8%AD%E8%AC%9B%E5%BA%A7-%E9%A6%AC%E5%A0%B4-%E4%BF%8A%E5%BD%B0-ebook/dp/B07YNB6QLJ)