TiCDCを使ってMySQLに同期してみる

## はじめに

[TiCDC](https://docs.pingcap.com/ja/tidb/stable/ticdc-overview) はTiDBのCDCツールで、TiDBの更新をTiDBやMySQLといったMySQLファミリに連携します。また、S3やKafka、Debeziumといったツールにも連携することが可能です。

本記事では、下記 TiDB DM 記事と同じ環境を使って、MySQL -> TiDBに同期した後、逆方向の同期をTiCDCで構成します。MySQLからTiDBに移行する際に、何かあったら切り戻せるようにTiDBへの更新をMySQLにも書いておきたい、そんなケースを念頭においています。

https://qiita.com/bohnen/items/7849d1e1b15bba067275

## 準備

前回記事をすべて実施しますが、一個だけ変更点があります。TiUP Playground起動の際に、ticdcも一緒に立ち上げます。

https://qiita.com/bohnen/items/7849d1e1b15bba067275

- MySQL (Docker) の起動
- Employeesサンプルデータベースのimport
- TiUP Playgroundでtidbとdmの起動 **※ここが変更**
- dmによるsync（一括移行）
- dmによる継続同期 (departmentsテーブルにレコードが連携される）

tiup playgroundを起動する際、下記のコマンドで起動します。

```bash
tiup playground v8.1.1 --dm-master 1 --dm-worker 1 --ticdc 1
```

それ以外は前回記事の流れをそのまま実施してください。

## DMタスクの停止

DMタスクを動かしたままだと、MySQL側のemployeesデータベースに更新があるとTiDBに同期されてしまい、場合によってはループしてしまいます。dm-taskを止めておきます。

```bash
> tiup dmctl --master-addr 127.0.0.1:8261 stop-task dm-task.yaml

{
    "op": "Delete",
    "result": true,
    "msg": "",
    "sources": [
        {
            "result": true,
            "msg": "",
            "source": "mysql-src",
            "worker": "dm-worker-0"
        }
    ]
}
```

## ticdc フィードの作成

ticdcは、`tiup cdc cli changefeed` コマンドから設定します。`--server` で設定するポートは8300、`--sink-uri` にMySQLの接続文字列を設定します。PKもUNIQUEもないテーブルは同期できないというワーニングが出ますが、今回は無視しましょう。`y`を入力します。

```bash
> tiup cdc cli changefeed create --server=http://127.0.0.1:8300 --sink-uri="mysql://root:<password>@127.0.0.1:3306" --changefeed-id="cdc-test"

Starting component cdc: /Users/bohnen/.tiup/components/cdc/v8.2.0/cdc cli changefeed create --server=http://127.0.0.1:8300 --sink-uri=mysql://root:root@127.0.0.1:3306 --changefeed-id=cdc-test
[WARN] Some tables are not eligible to replicate, because they do not have a primary key or a not-null unique key: []v2.TableName{v2.TableName{Schema:"lightning_task_info", Table:"conflict_records", TableID:114, IsPartition:false}}
Could you agree to ignore those tables, and continue to replicate [Y/N]
Note: If you don't want to ignore those tables, please set `force-replicate to` true in the changefeed config file.
y   ## ここでyを入力！！
Create changefeed successfully!

```

## 状態の確認

ticdcの状態を確認します。listサブコマンドを利用します。

```bash
> tiup cdc cli changefeed list --server=http://127.0.0.1:8300

Starting component cdc: /Users/bohnen/.tiup/components/cdc/v8.2.0/cdc cli changefeed list --server=http://127.0.0.1:8300
[
  {
    "id": "cdc-test",
    "namespace": "default",
    "summary": {
      "state": "normal",
      "tso": 454570814731714562,
      "checkpoint": "2024-12-13 09:34:03.990",
      "error": null
    }
  }
]
```

## 同期の確認

データが同期されるか確認してみます。TiDBでdepartmentsテーブルへのinsert、テーブルの作成をやってみましょう。

```sql
-- TiDB
> use employees;
> SELECT VERSION();
+--------------------+
| version()          |
+--------------------+
| 8.0.11-TiDB-v8.1.1 |
+--------------------+

> insert into departments values ('d011','TiDB Department');
> table departments;
+---------+--------------------+
| dept_no | dept_name          |
+---------+--------------------+
| d009    | Customer Service   |
| d005    | Development        |
| d010    | Example Department |
| d002    | Finance            |
| d003    | Human Resources    |
| d001    | Marketing          |
| d004    | Production         |
| d006    | Quality Management |
| d008    | Research           |
| d007    | Sales              |
| d011    | TiDB Department    |
+---------+--------------------+

> CREATE TABLE test(id int primary key, name varchar(20));
> INSERT INTO test VALUES(1, 'TiDB User');
> table test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | TiDB User |
+----+-----------+
```

MySQLにログインして、確認してみます。
```sql
-- MySQL
> use employees;
> SELECT VERSION();
+-----------+
| version() |
+-----------+
| 8.0.40    |
+-----------+

> table departments;
+---------+--------------------+
| dept_no | dept_name          |
+---------+--------------------+
| d009    | Customer Service   |
| d005    | Development        |
| d010    | Example Department |
| d002    | Finance            |
| d003    | Human Resources    |
| d001    | Marketing          |
| d004    | Production         |
| d006    | Quality Management |
| d008    | Research           |
| d007    | Sales              |
| d011    | TiDB Department    |
+---------+--------------------+

> table test;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | TiDB User |
+----+-----------+
```

DDLも含めて同期されていることがわかります。

## おわりに

TiDB DMとTiDB CDCを利用すると、MySQLとTiDBの並行運用が可能になるのがおわかりいただけたかと思います。両方のツールはともに豊富なオプションを持ちますので、実際にはもっと複雑なケースでも対応可能です。機会があればそういったオプションの深堀りもしていきたいと思います。