【OCI クラウド移行ガイド】Amazon RDS for MySQLからOracle Cloud MDSへの多段レプリケーションを設定してみた～MySQL編～

# OCIクラウド移行ガイドとは
オンプレミスやAWSなど、複数のプラットフォームからOracle Cloud Infrastructureへの移行プロジェクトに取り組んでいるクラウドエンジニア（@araidon,@kazunishi,@yama6）による、OCI移行手順をまとめたシリーズ記事です。
各回、サンプルワークロードから対象サービスを取り上げ、移行手順をガイドいたします。

# 移行したいサンプルワークロード
日々の業務でよく目にするサービスを中心に、サンプルワークロードとしてまとめてみました。このシリーズでは、主にAWSからの移行を取り上げます。
このワークロードは、ユーザがログインして、Web上で写真を共有するWebサービスをイメージしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/5d657078-030c-a277-544e-eebe031c74cf.png)

# 移行するサービス：Amazon RDS for MySQL
今回、移行対象とするのはAmazon RDS for MySQLです。
移行先はOracle CloudのMySQL PaaSである"MySQL Database Service"(略してMDS)です。

AWS RDS for MySQLからMDSに移行を実施する際、様々な手法/手段が考えられますが今回はMYSQLの機能を利用したレプリケーションを試してみたいと思います。

MDSはRDSとは異なりパブリックエンドポイントを持つことは現時点(2023年10月時点)ではできません。
VPNを張るのが一般的な方法かもしれませんが、今回は中継サーバを用いた多段レプリケーション実現してみたいと思います。
AWSに限らずVPNを設定できない事情がある際、他のクラウドやオンプレミスからMDSへのレプリケーション設定でも応用できるかと思います。

# 作業イメージ
イメージは以下の通り、
①RDSからインターネット経由でCompute上に構築した中継サーバの役割となるMySQLにレプリケーション
②中継サーバからVCN内の通信でMDSにレプリケーション
→結果としてRDSからMDSへのレプリケーションを実現
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/b439e694-435d-98dc-666d-17b6896a2b43.png)

# 作業の流れ
①MySQL on ComputeにてMySQLのセットアップ
②RDSの構築及び、レプリケーションに向けたセットアップ
③MySQL on ComputeとRDSのレプリケーション設定
④MDSの構築及び、MySQL on ComputeとMDSのレプリケーション設定
⑤RDSの更新作業がMDSまでレプリケーションされていることを確認

# ①MySQL on ComputeにてMySQLのセットアップ
## 1-1MySQLのインストール	
MySQLチームが提供しているyumの公式リポジトリをセットアップします
```
sudo yum install https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
```
RHEL8系のOSの場合、デフォルトで有効になっているMySQLモジュールを無効化する必要があるため、以下のコマンドを実行
```
sudo yum module disable mysql
```
mysqlのインストール
```
sudo yum install mysql-community-server
```
mysqlshellのインストール
```
sudo yum install mysql-shell
```

MySQLの開始
```
sudo systemctl start mysqld
```

MySQLにログインするため初期パスワードを確認しておきます
```
grep 'temporary password' /var/log/mysqld.log
```

中継サーバのMySQLにログインします
```
mysql -uroot -p
Enter password: <初期パスワードを入力>
```

MySQLの初期パスワードを変更しておきます。
```
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '変更後のパスワード';
```
```
exit;
```

## 1-2 MySQLのセットアップ
my.cnfに設定追加を実施します
```
vi /etc/my.cnf

#以下を追記
gtid_mode=ON
enforce-gtid-consistency=true
binlog_format=row
local-infile
log-bin=mysql-bin
log-slave-updates
```

my.cnfの設定変更を有効化するためMYSQLの再起動を実施します
```
sudo systemctl restart mysqld
```

Firewallの透過設定をしておきます。
```
sudo firewall-cmd --add-service=mysql --zone=public --permanent
sudo firewall-cmd --reload
```


MySQLにログインし、以下2項目が"ON"であることを確認します
　enforce_gtid_consistency = ON
　gtid_mode = ON

```
mysql> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery      | ON        |
| enforce_gtid_consistency         | ON        |
| gtid_executed                    |           |
| gtid_executed_compression_period | 0         |
| gtid_mode                        | ON        |
| gtid_next                        | AUTOMATIC |
| gtid_owned                       |           |
| gtid_purged                      |           |
| session_track_gtids              | OFF       |
+----------------------------------+-----------+
9 rows in set (0.01 sec)
```

# ②RDSの構築及び、レプリケーションに向けたセットアップ
## ②-1 RDSの構築
RDS構築の際、以下を実施する必要があります
①カスタムパラメータグループ にて以下2オプションの有効化を実施
　GTID_MODE=ON, ENFORCE_GTID_CONSISTENCY=ON
②構築時のオプションにて①で作成したカスタムパラメータグループの指定
③パブリックアクセスの有効化
④自動バックアップの有効化

## ②-2 RDSのセットアップ
中継サーバからRDSにアクセスを実施します
```
mysql -u admin -p -h <RDSエンドポイント>
```
レプリケーション用のユーザ作成を実施します
```
mysql> create user repl@'%' identified with mysql_native_password by 'repl';
Query OK, 0 rows affected (0.02 sec)
```
```
mysql> grant replication slave on *.* to 'repl'@'%';
Query OK, 0 rows affected (0.01 sec)
```
```
exit;
```

mysqlshellにてRDSのダンプ出力を実施します
```
mysqlsh admin@<RDSエンドポイント>:3306
```

# ③MySQL on ComputeとRDSのレプリケーション設定
## ③-1 中継サーバにRDSのダンプをロード
mysqlshellにて中継サーバにRDSのダンプデータをロードします
```
mysqlsh root@127.0.0.1
```
```
> util.loadDump("/home/opc/backup", {dryRun: false, updateGtidSet:'append'})
```

## ③-2 RDS→中継サーバへのレプリケーション設定
中継サーバのMySQLにアクセスします
```
mysql -uroot -p
```
以下コマンドを実行します
```
mysql> change REPLICATION SOURCE to source_host=<'RDSエンドポイント'>,source_user='repl', source_password='repl', source_auto_position=1 for channel 'channel1';
```
```
mysql> CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE = ('mysql.rds_%') for channel 'channel1';
```
```
mysql> start replica for channel 'channel1';
```

# ④MDSの構築及び、MySQL on ComputeとMDSのレプリケーション設定
## ④-1中継サーバのレプリケーション用ユーザ作成
中継サーバのMySQLにアクセスします
```
mysql -uroot -p
```
中継サーバとMDS用のレプリケーションユーザを作成します
```
mysql> create user usertemp@'%' identified with mysql_native_password by 'Manager@123';
```
```
mysql> grant replication slave on *.* to usertemp@'%';
```
```
mysql> grant all privileges on *.* to usertemp@'%';
```

## ④-2中継サーバのダンプデータを出力/MDSにダンプデータをロード
mysqlshellにて中継サーバにアクセスします
```
mysqlsh root@127.0.0.1
```
ダンプを出力します
```
util.dumpInstance("/home/opc/backup2", {dryRun: false, ocimds: true, compatibility: ["strip_definers", "strip_restricted_grants"], consistent:false})
```

MDSmysqlshellでアクセスして中継サーバのダンプをロードします
```
mysqlsh admin@10.0.1.189
```
```
util.loadDump("/home/opc/backup2", {dryRun: false, updateGtidSet:'append'})
```

## ④-3 OCI WebコンソールにてMDSと中継サーバのレプリケーション設定
対象MDSの画面より"チャネル"タブより"チャネルの作成"を実施します
　ホスト名：<中継サーバのプライベートIPアドレス>
　MySQLポート：3306
　ユーザ名：usertemp
　パスワード：Manager@123
　パスワードの確認：Manager@123
　SSLモード：無効(DISABLED)
　Applierユーザー名：admin
　チャネル名：channel1
　主キーのない表：許可(ALLOW)
　レプリケーション遅延：空白
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/0d7abf1a-6ad1-956e-0695-3c5a8595740b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/dfcd4175-475e-2110-77d7-d194b99e218e.png)

チャネル作成後、ステータスが"アクティブ"になることを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/cde4ca27-bed0-521a-9d0d-54305ab5d0e2.png)

## ⑤RDSの更新作業がMDSまでレプリケーションされていることを確認
同期確認のため、マスタであるRDSにアクセスし簡易的にDB作成をします
```
mysql -u admin -p -h <RDSのエンドポイント>
```
```
mysql> CREATE DATABASE rpl2;
mysql> CREATE TABLE rpl2.test(id int AUTO_INCREMENT, col1 CHAR(10), PRIMARY KEY(id));
mysql> INSERT INTO rpl2.test VALUES(1, "TEST");
mysql> SELECT * FROM rpl2.test;
+----+------+
| id | col1 |
+----+------+
|  1 | TEST |
+----+------+
1 row in set (0.01 sec)
```

同期が取れているかスレーブである中継サーバMySQLにアクセス
```
mysql -uroot -p
```
```
mysql> SELECT * FROM rpl2.test;
+----+------+
| id | col1 |
+----+------+
|  1 | TEST |
+----+------+
```
同様に同期が取れているかスレーブであるMDSにアクセス。
```
mysql -u admin -p -h 10.0.1.61
```
```
mysql> SELECT * FROM rpl2.test;
+----+------+
| id | col1 |
+----+------+
|  1 | TEST |
+----+------+
```

無事にRDSでの更新作業が中継サーバ/MDSにレプリケーションされていることが確認できました。

# 参考

https://oracle-japan.github.io/ocitutorials/beginners/creating-mds/

https://oracle-japan.github.io/ocitutorials/beginners/creating-mds-channel/#3-mds%E3%81%AE%E4%BD%9C%E6%88%90%E3%82%BD%E3%83%BC%E3%82%B9%E7%94%A8%E3%81%AEmds%E3%83%AC%E3%83%97%E3%83%AA%E3%82%AB%E7%94%A8%E3%81%Aemds

https://qiita.com/chibatty/items/86549498a0e505aeff5b