はじめに
前の記事で紹介した、MySQLとTiDBのデータ移行を行うツールTiDB DMですが、
TiUP Playground 1.16.1 からPlaygroundに含まれるようになり、簡単に試せるようになりました。
本記事ではDMを使ってMySQLとTiDBを同期してみます。データ移行だけではなくて、MySQLに更新したデータもTiDBに同期されるのがわかると思います。
AWSのDMS(Data Migration Service)のようなツールですが、以外と簡単なのでぜひ試してみてください。
準備
本記事では MySQL をDockerを使って起動します。また、MySQL側にいれるサンプルデータとして、Employeeデータベース を利用します。あらかじめ用意しておきましょう。
TiUPとPlaygroundの設定については、下記の記事をご覧ください。
以前TiUPをインストールしている方は、Playgroundを最新にしておく必要があります。
> tiup update playground
MySQLの起動とサンプルデータの読み込み
MySQLを起動します。MySQLのバイナリはDockerのv8.0.40を利用して、my.confだけ渡す形にします。
my.confは下記の通りです。ここで必要な設定はbinlogの形式をROWにしておくことです。
これを、conf.d
ディレクトリ下に置きます。
[mysqld]
bind-address = 0.0.0.0
character-set-server=utf8
collation-server=utf8_bin
default-storage-engine=INNODB
transaction-isolation=READ-COMMITTED
server-id = 100
binlog_format = row
log_bin = /var/lib/mysql/mysql-bin.log
次のようにしてMySQLを起動します。 は各自設定してください。
docker run --name mysql -v ./conf.d:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=<password> -d -p 3306:3306 mysql:8.0.40
TiDB DMは MySQL v8.4で廃止された SHOW MASTER STATUS
をチェックに使っているため、ここではv8.0.40を利用しています。(このチェックは設定で実施しないようにすることが可能)
起動したら、サンプルデータを投入します。サンプルデータのあるディレクトリに移動して
mysql -u root -h 127.0.0.1 -p<password> < employees.sql
これでMySQL側の準備は完了です。
TiDB Playgroundの起動
TiDB Playgroundを起動します。TiDB PlaygroundをDMつきで起動するために、オプションをセットします。
> tiup playground v8.1.1 --dm-master 1 --dm-worker 1
Start pd instance: v8.1.1
Start tikv instance: v8.1.1
Start tidb instance: v8.1.1
Start dm-master instance: v8.1.1
Waiting for dm-master instances ready
127.0.0.1:8261 ... Done
Start dm-worker instance: v8.1.1
Waiting for tidb instances ready
127.0.0.1:4000 ... Done
Start tiflash instance: v8.1.1
Waiting for tiflash instances ready
127.0.0.1:3930 ... Done
🎉 TiDB Playground Cluster is started, enjoy!
Connect TiDB: mysql --host 127.0.0.1 --port 4000 -u root
Connect DM: tiup dmctl --master-addr 127.0.0.1:8261
TiDB Dashboard: http://127.0.0.1:2379/dashboard
Grafana: http://127.0.0.1:3000
これで、TiDBプロセス一式とDMが起動しました。
DM設定ファイルの準備
DMを利用するためには、ソースDBの定義とタスク定義を作成する必要があります。
ソースDBの定義
ソースDBでは、MySQL側の接続設定を記載します。パスワードは先程Dockerで起動したMySQLに設定したものです。
source-id: "mysql-src"
from:
host: "127.0.0.1"
user: "root"
password: "<password>"
port: 3306
DMタスク定義
DMタスク定義では、DMのタスク詳細を記載します。主に、DMのタスクの種類(全量データ移行、継続同期、両方)、タスクの対象とするデータベースやテーブルのフィルタなどを記載します。
今回はemployeesデータベースを全量データ移行と継続の両方で同期(task-mode: all
)するようにします。
name: dm-task
task-mode: all
target-database:
host: "127.0.0.1"
port: 4000
user: "root"
password: ""
mysql-instances:
- source-id: "mysql-src"
block-allow-list: "ba-rule1"
block-allow-list:
ba-rule1:
do-dbs: ["employees"]
DM設定と実行
DMを設定するには、dm-ctl
コマンドを利用します。TiUPから利用できます。
まずソース定義を使ってソースDBを定義します。
> tiup dmctl --master-addr=127.0.0.1:8261 operate-source create mysql.yaml
Starting component dmctl: /Users/bohnen/.tiup/components/dmctl/v8.1.0/dmctl/dmctl --master-addr=127.0.0.1:8261 operate-source create mysql.yaml
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"source": "mysql-src",
"worker": "dm-worker-0"
}
]
}
次にタスク定義を使ってタスクを実行します。ワーニングが出ますが、ここでは気にしなくて大丈夫です。
> tiup dmctl --master-addr 127.0.0.1:8261 start-task dm-task.yaml
Starting component dmctl: /Users/bohnen/.tiup/components/dmctl/v8.1.0/dmctl/dmctl --master-addr 127.0.0.1:8261 start-task dm-task.yaml
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"source": "mysql-src",
"worker": "dm-worker-0"
}
],
"checkResult": "fail to check synchronization configuration with type: no errors but some warnings
...
タスクの実行状況はステータスコマンドで確認できます。SubTaskStatusのsyncedがtrueになっていれば、同期完了です。
tiup dmctl --master-addr 127.0.0.1:8261 query-status dm-task
Starting component dmctl: /Users/bohnen/.tiup/components/dmctl/v8.1.0/dmctl/dmctl --master-addr 127.0.0.1:8261 query-status dm-task
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"sourceStatus": {
"source": "mysql-src",
"worker": "dm-worker-0",
"result": null,
"relayStatus": null
},
"subTaskStatus": [
{
"name": "dm-task",
"stage": "Running",
"unit": "Sync",
"result": null,
"unresolvedDDLLockID": "",
"sync": {
"totalEvents": "1",
"totalTps": "0",
"recentTps": "0",
"masterBinlog": "(binlog.000003, 66378917)",
"masterBinlogGtid": "",
"syncerBinlog": "(binlog.000003, 66378917)",
"syncerBinlogGtid": "",
"blockingDDLs": [
],
"unresolvedGroups": [
],
"synced": true,
...
継続同期
この状態でDMはMySQLのbinlogを監視し、更新をTiDB側に連携します。
試しにMySQL側のdepartmentsテーブルに行を追加してみます。
-- MYSQLに接続
> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 8.0.40 |
+-----------+
> use employees;
> insert into departments values('d010','Example Department');
> table departments;
+---------+--------------------+
| dept_no | dept_name |
+---------+--------------------+
| d001 | Marketing |
| d002 | Finance |
| d003 | Human Resources |
| d004 | Production |
| d005 | Development |
| d006 | Quality Management |
| d007 | Sales |
| d008 | Research |
| d009 | Customer Service |
| d010 | Example Department | -- 追加した行
+---------+--------------------+
TiDB側も確認してみます。
SELECT VERSION();
+--------------------+
| version() |
+--------------------+
| 8.0.11-TiDB-v8.1.1 |
+--------------------+
> table departments;
+---------+--------------------+
| dept_no | dept_name |
+---------+--------------------+
| d001 | Marketing |
| d002 | Finance |
| d003 | Human Resources |
| d004 | Production |
| d005 | Development |
| d006 | Quality Management |
| d007 | Sales |
| d008 | Research |
| d009 | Customer Service |
| d010 | Example Department | -- 同期された行
+---------+--------------------+
同期されていることが確認できました。
おわりに
TiDB DMはMySQLからTiDBへのデータ移行を行うツールです。AWS DMSと同様に一括移行と継続同期をサポートし、また今回は触れていませんがmasterノード、workerノードを複数持つことができ耐障害性を高めた構成にすることもできます。
Playground版では簡単に起動できるので設定の確認やお試しにもってこいです。ぜひ活用してみてください。(多分TiDB Cloudに対しても利用できる気がしますが、また別の記事で試してみることにします)