🗿

【TiDB移行】sync-diff-inspector使ってみる

に公開

この記事は レバテック開発部 Advent Calendar 2025 9日目の記事です。

これは

sync-diff-inspectorを使ってMySQL互換のデータベース間のデータ差分チェックを最低限の構成でやってみます。

sync-diff-inspectorって?

MySQLプロトコルを使用してデータベースに保存されたデータを比較するためのツールです。MySQL〜TiDB間といったデータの差分を比較できます。また、少量のデータに不整合がある場合の修復用のSQLを自動生成する機能も備わっています。

きっかけ

全社的にAWS RDSからTiDBへ移行を行なっておりデータレプリケーション中のデータの整合性を検証するために調査しました。

動確する上での前提条件

  1. ソース(Aurora)、ターゲット(TiDB)ともにスキーマ構造が同じ状態
  2. ソース〜ターゲット間でレプリケーションされている又は同等量のデータが存在する

※ 検証を行うには、多少のレコード数のずれやデータの違いがあったほうが良いかもしれません
※ 今回はtest_schema.sample_data_types(スキーマ名.テーブル名)を題材にします

また、筆者は MacBook(Apple M1 Pro) で実行しました。

インストール

早速インストールしていましょう。
※TiDBのコンポーネントをまとめたパッケージマネージャー(TiUP)経由でインストールします。

# TiUP インストール(未インストールの場合)
$ curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
# シェルを再読み込み
$ source ~/.zshrc
# TiUP 自体を最新化
$ tiup update --self
# sync_diff_inspector をインストール
$ tiup install sync_diff_inspector
# パス設定(versionはよしなに変えてください)
$ echo "export PATH=$PATH:~/.tiup/components/sync-diff-inspector/v9.0.0-beta.1" >> ~/.zshrc
# シェルを再読み込み
$ source ~/.zshrc
# バージョン確認
$ sync_diff_inspector --version

設定ファイルの作成

任意のディレクトリ下でconfig.tomlファイルを作成します。
今回は動作検証を行う目的で最低限の構成ファイルとさせていただきます。
より詳細に設定したい場合は公式ドキュメントを参考にしてください。

config.toml
######################### Global config #########################
check-thread-count = 4 # データチェックに使う goroutine(並列処理のスレッド)の数。実際にはこの値より少し多めのDB接続が作られる。
export-fix-sql = true # 不整合(差分)が見つかったテーブルを修正するためのSQL文を出力する。
check-data-only = false # データだけを比較して、テーブル構造は比較しない機能。※実験的機能なので本番では推奨されない。
check-struct-only = false # テーブル構造のみ比較して、データは比較しない。
skip-non-existing-table = true # 片方のDBにしか存在しないテーブルは比較をスキップするかどうか。

######################### Datasource config #########################
[data-sources]
[data-sources.mysql1]
    host = "{ソースDBエンドポイント}"
    port = "{ソースDBポート}"
    user = "{ソースDBユーザー名}"
    password = "{ソースDBパスワード}"
    route-rules = ["rule1"]
[data-sources.mysql2]
    host = "{ターゲットDBエンドポイント}"
    port = "{ターゲットDBポート}"
    user = "{ターゲットDBユーザー名}"
    password = "{ターゲットDBパスワード}"

########################### Routes ##############################
[routes]
[routes.rule1] # rule1 は任意のIDです。上記の `data-sources.route-rules` で参照されます。
schema-pattern = "test_schema"      # データソース側のスキーマ名にマッチ。ワイルドカード "*" と "?" が利用可能
table-pattern = "*"                 # データソース側のテーブル名にマッチ。ワイルドカード "*" と "?" が利用可能
target-schema = "test_schema"       # ターゲットDB側のスキーマ名
target-table = ""                   # ターゲットDB側のテーブル名

######################### task config #########################
[task]
    output-dir = "./output"
    source-instances = ["mysql1"]
    target-instance = "mysql2"
    # 下流(ターゲット)データベースで比較対象とするテーブル。
    # それぞれ「schema.table」の形式で指定します。
    # "?" は任意の1文字、"*" は任意の長さの文字列にマッチします。
    # 詳細なマッチルールは golang regexp(Google RE2)の構文を参照: https://github.com/google/re2/wiki/Syntax
    # target-check-tables = ["schema*.table*", "!c.*", "test2.t2"]
    target-check-tables = ["test_schema.sample_data_types"]
    # (オプション)特定のテーブルに対する追加設定。
    # Config1 は後述の table config の例にて定義されています。
    target-configs = []

実行

$ sync_diff_inspector --config=config.toml

実行結果

実行が完了するとoutputディレクトリが生成されます。

shuto@PC-777 output $ tree
.
├── checkpoint
├── fix-on-tidb0
│   └── test_diff:sample_data_types:0:0-0:0.sql
├── summary.txt
└── sync_diff.log

3 directories, 4 files

fix-on-tidb0: 差分が発生していたデータの修復SQLが格納される
summary.txt: 検証したテーブルや結果などの統計情報が格納される
sync_diff.log: 検証中のログが格納される

一部制約あり

実際にsync-diff-inspectorを利用してみると、いくつか注意すべき制約があります。

1. オンライン比較でできないこと

データ整合性のチェックに特化したツールであり、レプリケーションラグなどは考慮されないので誤検知されるリスクがあります。
夜間などソース側での書き込み頻度が低い時間帯やメンテナンス等を実施して検証する運用が望ましいです。

2. サポートされないデータ型

MySQL 互換の比較を想定しているものの、すべてのデータ型に対応しているわけではありません。特にJSON, BIT, BLOB型などはサポート範囲外であり比較時の挙動に注意が必要なので事前にサンプルで確認しておくのが安全です。

まとめ

今回の検証を通して感じたポイントは以下の2つです。

1. 最小構成で素早く比較できる

config.tomlを1つ用意するだけで、
「Aurora → TiDB」といった異なるDBMS間の整合性を手軽にチェックできます。
初動の調査としても、仕組み作りとしても扱いやすいのが魅力です。

2. 差分の可視化と修復 SQL の自動作成がとても便利

差分がどのレコードに発生しているかを確認でき、
さらに必要に応じて修復用SQLまで吐き出してくれるため、
「どこが違ってどう直せばよいか」がすぐに確認できる点も良いなと思いました。

今回の記事が、これからデータ移行やレプリケーション検証に取り組む方の助けになれば幸いです。ぜひ一度、手元で試してみてください。

参考文献

レバテック開発部

Discussion