CData Syncを利用したMySQL間のデータベースレプリケーション -差分レプリケーション-

## はじめに
CData Syncを利用してMySQL間のデータベースレプリケーション、その中でも差分レプリケーションを実施してみました。

なお、本内容は前回記事の続きの内容になります。
https://qiita.com/haflaf7843/items/50200baff5a2e5cf3181

前回記事の内容では、MySQLをデータソースに選択している上で、レプリケーションの種類として[標準(個別設定)]を利用していたため、フルロードのレプリケーションとなっていました。

今回記事の内容では、レプリケーションの種類として[変更データキャプチャ]を利用し、MySQLのバイナリログを利用した差分レプリケーションを実施することになります。

## 構成 ※AWS環境
EC2のWindows ServerにMySQLとCData Syncを導入し、RDSのMySQLにレプリケーションを行います。

・EC2
Windows Server 2019
MySQL 8.0.40
CData Sync 24.3.9121

・RDS
MySQL 8.0.39

なお、CData Syncのライセンスは、30日間無償の評価版ライセンスを利用しています。

## 実施内容
ここからは下記の流れで手を動かしていきます。

1.MySQLの設定
2.ジョブの設定
3.ジョブの実行

なお、各データベースとの接続には、前回記事で作成した各コネクタを利用することを前提にしています。
事前に、データソース側MySQLに準備したcdatatestというデータベースにて、saladというテーブルを作成しました。
上記テーブルを同期先側MySQLに準備したcdatatest2というデータベースにレプリケーションしていきます。

### 1.MySQLの設定
まず、MySQLをデータソースとしたCDC(変更データキャプチャ)機能を利用するためには、データソース側MySQLにてバイナリログが有効になっている必要があります。
https://cdn.cdata.com/help/ASK/jp/sync/MySQL-Source.html#%E3%83%90%E3%82%A4%E3%83%8A%E3%83%AA%E3%83%AD%E3%82%B0%E3%81%AE%E6%9C%89%E5%8A%B9%E5%8C%96%E5%A4%89%E6%9B%B4%E3%83%87%E3%83%BC%E3%82%BF%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E7%94%A8

下記のようにlog_binシステム変数の値がONとなっていれば、バイナリログが有効と確認できます。
```
mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.09 sec)
```
※MySQL8.0であれば、既定でバイナリログが有効状態になっているようです。
https://dev.mysql.com/doc/refman/8.0/ja/binary-log.html

また、データソース側のコネクタとして利用するユーザがバイナリログを確認する権限を有していることが必要となります。

今回は、該当ユーザにREPLICATION CLIENTとREPLICATION SLAVE権限を付与しました。
```
mysql> grant REPLICATION CLIENT on *.* to 'cdatauser'@'localhost';
Query OK, 0 rows affected (0.09 sec)

mysql> grant REPLICATION SLAVE on *.* to 'cdatauser'@'localhost';
Query OK, 0 rows affected (0.17 sec)
```

### 2.ジョブの設定
CDC(変更データキャプチャ)機能を利用したデータベースレプリケーションを行うジョブを作成していきます。
レプリケーションの種類としては、[変更データキャプチャ]を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977704/a052fd03-0cfb-b7c2-5358-9d8bd41e3d4c.png)

ジョブの作成が完了すると、一覧に作成したジョブが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977704/07ec3e0f-8c9b-407c-a423-ab5c32f6fa0c.png)

次に、ジョブにタスクを追加していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977704/7602d0b5-9619-3f81-76b9-50b52d23d280.png)

タスクの追加が完了すると、一覧に追加したタスクが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977704/6894d7be-71a8-a5f6-0c8f-6608d0fa87e2.png)

### 3.ジョブの実行
作成したジョブを実行していきます。
※テーブルの内容を変更せず、2回連続でジョブを実行します。

実行後にジョブ履歴を確認すると、影響を受けたレコードが1回目は2行(対象テーブルの全行数)、2回目は0行になっていました。
ここで、1回目の実行ではフルロードでレプリケーションを行い、2回目の実行では差分レプリケーションを行っていることを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977704/2509eb52-344b-0688-c4b5-8f8cd8eab83b.png)

ジョブ実行完了に伴い、実際にMySQLのデータベースを確認しました。

下記のように、データソース側のcdatatestデータベースのsaladテーブルが同期側のcdatatest2データベースにレプリケーションされていました。

また、CDC(変更データキャプチャ)機能を利用したレプリケーションを実施すると、レコードの論理削除に関する_cdatasync_deletedカラムが新しく追加されていました。

```
<データソース側>
mysql> use cdatatest;
Database changed

mysql> SHOW TABLES;
+---------------------+
| Tables_in_cdatatest |
+---------------------+
| salad               |
| yakiniku            |
+---------------------+
2 rows in set (0.14 sec)

mysql> select * from salad;
+----+--------+
| id | name   |
+----+--------+
|  1 | tomato |
|  2 | potato |
+----+--------+
2 rows in set (0.00 sec)
```
```
<同期先側 - レプリケーション前>
mysql> use cdatatest2;
Database changed

mysql> SHOW TABLES;
+----------------------+
| Tables_in_cdatatest2 |
+----------------------+
| yakiniku             |
+----------------------+
1 row in set (0.02 sec)
```
```
<同期先側 - レプリケーション後>
mysql> use cdatatest2;
Database changed

mysql> SHOW TABLES;
+----------------------+
| Tables_in_cdatatest2 |
+----------------------+
| salad                |
| yakiniku             |
+----------------------+
2 rows in set (0.00 sec)

mysql> select * from salad;
+----+--------+----------------------------------------+
| id | name   | _cdatasync_deleted                     |
+----+--------+----------------------------------------+
|  1 | tomato | 0x00                                   |
|  2 | potato | 0x00                                   |
+----+--------+----------------------------------------+
2 rows in set (0.00 sec)
```

最後に、データソース側のcdatatestデータベースのsaladテーブルのレコードを1行UPDATEした上で、再度ジョブを実行してみました。
※UPDATEとしては、idが2のレコードについてnameをpotatoからonionに変更したのみです。

結果としては、想定通りに影響を受けたレコードが1行のみになっており、差分レプリケーションがされたことを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977704/40bdc58d-ac41-11e9-7d7c-3e0c8e7a44a9.png)

ジョブ実行完了に伴い、実際にMySQLのデータベースを確認しました。

下記のように、idが2のレコードについてnameがpotatoからonionにUPDATEされており、差分レプリケーションされていました。
```
<データソース側>
mysql> use cdatatest;
Database changed

mysql> select * from salad;
+----+--------+
| id | name   |
+----+--------+
|  1 | tomato |
|  2 | onion  |
+----+--------+
2 rows in set (0.00 sec)
```
```
<同期先側 - レプリケーション前>
mysql> use cdatatest2;
Database changed

mysql> select * from salad;
+----+--------+----------------------------------------+
| id | name   | _cdatasync_deleted                     |
+----+--------+----------------------------------------+
|  1 | tomato | 0x00                                   |
|  2 | potato | 0x00                                   |
+----+--------+----------------------------------------+
2 rows in set (0.03 sec)
```
```
<同期先側 - レプリケーション後>
mysql> use cdatatest2;
Database changed

mysql> select * from salad;
+----+--------+----------------------------------------+
| id | name   | _cdatasync_deleted                     |
+----+--------+----------------------------------------+
|  1 | tomato | 0x00                                   |
|  2 | onion  | 0x00                                   |
+----+--------+----------------------------------------+
2 rows in set (0.00 sec)
```

## おわりに
今回は、CDC(変更データキャプチャ)機能を利用した差分レプリケーションを実施してみました。

実際のところ、CDC機能を利用する上でのMySQL側の付与権限に多少躓きました。
今回は、REPLICATION CLIENTとREPLICATION SLAVE権限をざっくりと付与しましたが、よりスマートに権限付与もできたのかもしれません。

この点は、自分が学習する上でのポイントになりそうです。

下記は、本文記載外の参考URLです。
https://www.cdata.com/jp/sync/connections/#sources
https://cdn.cdata.com/help/ASK/jp/sync/Change-Data-Capture.html
https://www.cdata.com/jp/blog/db-cdc-sync
https://www.cdata.com/jp/blog/mysql-cdc-sync