TiDB User Day 2024のアーカイブ動画を公開中!詳細を見る
tidb-dm-banner

※このブログは2022年9月6日に公開された英語ブログ「How TiDB Processes DML in Data Migration」の拙訳です。

著者: Minghao Guo (PingCAPデータベースエンジニア)
編集者:  Calvin Weng、Tom Dewan

オープンソースのNewSQLデータベースであるTiDBは、水平方向のスケーラビリティを特徴としており、ユーザーを複数のシャードにまたがったクエリやオペレーションの複雑さから保護することができます。しかし、ユーザーがシャーディング環境SからTiDBに移行する際、その複雑さはそのまま残ります。Data Migration (DM) ツールは、シャーディングを必要とするリレーショナルデータベースからTiDBへの完全なデータ移行と増分データレプリケーションをサポートします。

DMのコアコンポーネントであるSyncが、binlogレプリケーションのワークフローを通じてDML (Data Manipulation Language)ステートメントを処理する方法を説明します。Syncがどのようにbinlogイベントを読み取り、フィルタリング、ルーティング、変換、実行を最適化するかについて説明します。

Sync binlogレプリケーションのワークフロー

次の図は、binlogレプリケーションのワークフローを示しています。

Syncフロー

このワークフローで、Syncは以下の機能を持ちます: 

  1. MySQL/MariaDBのbinlogまたはリレーログを読み込みます。
  2. binlogイベントを変換します。
    • binlog Filterモジュールは、binlog形式にしたがってbinlogイベントをフィルタリングします。filterパラメータを使って設定することができます。
    • Routingモジュールは、ルーティングルールを使ってデータベース名やテーブル名を変換します。このモジュールは、routeパラメータを使用して設定することができます。
    • Expression Filterモジュールは、SQLを使用して、binlogイベントをフィルタリングします。expression-filterパラメータを使用して、このモジュールを設定することができます。
  3. DMLステートメントを最適化します。
    • Compactorモジュールは、同じ行(同じ主キー)に対する複数の操作を1つにまとめます。この機能は、 syncer.compact パラメータで有効にすることができます。
    • Causalityモジュールは、まず異なる行(異なる主キー)に対する操作の競合を検出し、次に競合しない操作をグループ化して同時処理します。
    • Mergerモジュールは、複数のbinlogイベントを1つのDMLステートメントに統合します。この機能は、 syncer.multiple-rowsパラメータで有効にすることができます。
  4. 下流データベースへのDMLを実行します。
  5. binlogポジション、またはグローバルトランザクションID (GTID) をチェックポイントとして定期的に保存します。

最適化ロジック

Compactor

DMは、上流のbinlogファイルを読み、TiDBに変更をレプリケートします。Compactorモジュールは、期間内に1つの行の複数の変更を取得した場合、これらの変更を1つに圧縮します。これにより、下流への負荷が軽減され、スループットが向上します。次の例は、変更がどのように圧縮されるかを示しています:

INSERT + UPDATE => INSERT
INSERT + DELETE => DELETE
UPDATE + UPDATE => UPDATE
UPDATE + DELETE => DELETE
DELETE + INSERT => UPDATE

Causality

一般に、MySQLのBinlogイベントは順番にレプリケートされます。しかし、このメカニズムでは、1秒あたりのクエリ数が多い(QPS)シナリオでは、低いレプリケーションのレイテンシーを実現することはできません。さらに、すべてのbinlogイベントが競合するわけでもありません。DMは、競合するBinlogイベントを特定するために、Causalityと呼ばれる競合検出メカニズムを採用しています。Causalityモジュールは、disjoint-set構造のようなアルゴリズムを使用して、競合するBinlogイベントと、競合しないBinlogイベントをグループ化します。同じ競合グループのDML文は順次実行され、非競合グループのDML文は最適なパフォーマンスを得るために並行実行されます。

Merger

MySQLレプリケーションプロトコルでは、1つのbinlogイベントが1つの変更操作に対応すると規定されています。DMは、Mergerモジュールで複数のbinlogイベントを1つのDML文に統合し、統合されたコマンドをTiDBに実行することができます。これは、ネットワークの相互作用によるオーバーヘッドを減らすのに役立ちます。以下の例は、binlogイベントがどのように統合されるかを示しています:

INSERT tb(a,b) VALUES(1,1);
+ INSERT tb(a,b) VALUES(2,2);
= INSERT tb(a,b) VALUES(1,1),(2,2);
UPDATE tb SET a=1, b=1 WHERE a=1;
+ UPDATE tb SET a=2, b=2 WHERE a=2;
= INSERT tb(a,b) VALUES(1,1),(2,2) ON DUPLICATE UPDATE a=VALUES(a), b=VALUES(b)
DELETE tb WHERE a=1
+ DELETE tb WHERE a=2
= DELETE tb WHERE (a) IN (1),(2);

実行ロジック

DML生成

DMにはスキーマトラッカーが内蔵されており、上流と下流のデータベースのスキーマを記録することができます。DMは、DDL (Data Definition Language) 文を受け取ると、スキーマトラッカー内のテーブル構造を更新します。DMはDML文を受け取ると、スキーマトラッカー内のテーブル構造に従って、対応するDMLを生成します。処理ロジックは以下が挙げられます:

  • 完全レプリケーションと増分レプリケーションの両方のタスクが進行中の場合、Syncモジュールは上流の完全レプリケーションからダンプされたテーブル構造を最初の上流テーブル構造として使用します。
  • 増分レプリケーションタスクのみが開始された場合、MySQL binlogファイルにはテーブル構造が存在しません。Syncモジュールは、対応する下流 テーブル構造を最初の上流 テーブル構造として使用します。
  • 上流と下流でテーブル構造が異なる場合があります。例えば、下流側のテーブルにカラムが追加されていたり、下流側と上流側のテーブルで主キーが異なる場合があります。データ複製間の整合性を確保するため、DMは対応する下流テーブルの主キーとユニークキーを記録します。
  • DML文を形成するために、DMでは以下が行われます:
    1. スキーマトラッカーに記録された上流テーブル構造でDMLカラムを生成します。
    2. binlogファイルに記録された列の値をもとに、DMLの列の値を生成します。
    3. schema trackerに記録されている下流の主キーとユニークキーをもとに、DMのWHERE条件を生成します。下流のテーブルにユニークキーがない場合、DMはbinlogファイルにあるすべてのカラムの値をWHERE条件として使用します。

ワーカー数

前述したように、Causalityモジュールは競合検出アルゴリズムを用いてbinlogイベントを複数のグループに分割し、下流データベースで同時実行します。DMの同時実行は、 syncer.worker-count パラメータで制御します。下流のTiDBノードのCPU使用率が高くない場合は、並行処理を増やすことでデータレプリケーションのスループットを向上させることができます。

バッチ処理

DMは、複数のDML文を1つのトランザクションに蓄積し、下流のデータベースで実行します。DML文を受信すると、DMLワーカーはその文をキャッシュに追加します。キャッシュされた文の数が閾値を満たすか、長期間DML文を受信しない場合、DMLワーカーはキャッシュされたDML文を下流データベースに対して実行します。キャッシュされる文の数は、syncer.batch パラメータで設定することができます。

安定した安全な複製を可能にするオペレーター

チェックポイント

デフォルトでは、DMのチェックポイントは30秒ごとに更新されます。複数のDMLワーカーが存在するため、チェックポイント処理では、レプリケーションのための現在のチェックポイントとして使用する最新のbinlog位置を見つける必要があります。この時点以前のBinlogイベントは、TiDBに正常にレプリケートされます。

トランザクションの一貫性

DMレプリケーションは行単位です。DMは上流トランザクションを複数の行に分割し、それをDMLワーカーに分配して同時実行します。DMレプリケーションタスクがエラーや意図的に中断されると、下流のデータベースは上流トランザクションのDML文が部分的に複製された中間状態にとどまることがあります。このような場合、下流側のデータベースは上流側のデータベースと不整合になります。このような不整合をできるだけ避けるため、DMバージョン5.3からはレプリケーションタスクが中断される前に10秒間の待ち時間を設けるようにしました。しかし、待機時間内に上流トランザクションのレプリケーションに失敗すると、不整合が発生する可能性は残されています。

セーフモード

実行ロジックのセクションで示したように、DMLの実行とチェックポイントの更新は同期ではありません。つまり、チェックポイントの更新と下流のbinlogレプリケーションはアトミックでない可能性があります。DMがエラーで中断した場合、チェックポイントは中断時間より前のリカバリーポイントを記録している可能性があります。その結果、レプリケーションタスクが再起動したときに、重複レプリケーションが発生する可能性があります。つまり、DMは実際にはat-least-once処理のロジックを提供しており、データが複数回処理される可能性があるということです。例外エラーの発生後にDMを再起動すると、DMはセーフモードに入り、重複データの取り込みをサポートします。そのロジックは以下の通りです:

  • DMタスクがグレースフルに中断された場合、DMは下流データベースに対してキャッシュされたすべてのDML文を実行し、チェックポイントをリフレッシュします。この場合、DMは再起動してもセーフモードにはなりません。チェックポイント前のデータはすでにレプリケートされており、チェックポイント後のデータはまだレプリケートされていません。また、重複してレプリケーションされることはありません。
  • DMタスクがエラーで中断した場合、DMはまず下流のデータベースに対して、キャッシュされたすべてのDML文の実行を試みます。この試みは、データ競合の可能性があるため、失敗することがあります。次に、DMは最新の上流binlog位置をメモリから取得し、 safemode_exit_point(セーフモードの終了点を意味する)として記録します。この終了点と最新のチェックポイントは、下流で比較のためにリフレッシュされます。タスク再開時に考えられる条件は以下の通りです:
    • チェックポイントの位置が終了点と同じであれば、DMが中断されたときにすべてのbinlogイベントが下流のデータベースにレプリケートされることを意味します。そのため、タスクはgracefully suspendedタスクと同様に処理され、DMがセーフモードに移行することはありません。
    • チェックポイントの位置が終了点よりも早い場合、キャッシュされたいくつかのDML文がダウンストリームで失敗したことを意味します。この場合、DMはセーフモードを有効にして、チェックポイントとsafemode_exit_pointの間でbinlogイベントを複製します。これらのイベントのレプリケーションが重複している可能性があります。
    • safemode_exit_pointに値がない場合、safemode_exit_point の更新操作に失敗したか、DMが強制終了されたことを意味します。この場合、DMはレプリケーションプロセスの終了点を特定することができません。そのため、タスク再開時に、DMはデフォルトで2回のチェックポイントの間に1分間のセーフモードを有効にします。その後、DMはセーフモードを停止し、通常のレプリケーションプロセスが再開されます。

セーフモードでは、DMはDML文を以下のように変換して、binlogを最低1回は複製できるようにします:

  • 上流のINSERT文は、REPLACE文に変換されます。
  • 上流のUPDATE文は、DELETE+REPLACE文に変換されます。

まとめ

Syncは多くのシナリオで問題なく機能しますが、並列実行前にトランザクションを分割する処理ロジックは、いくつかの問題を引き起こす可能性があります。たとえば、上流とのステータスの不整合により、下流へのレプリケーションが中断されることがあります。下流側のデータベースから変更データを取得するために、安全モードで重複したデータのレプリケーションが実行されるかもしれません。

TiDBを体験するには、コミュニティエディションまたはTiDB Cloud無料トライアルをお試しください。日本語ドキュメントのTiDBクイックスタートガイド、またはTiDB Cloudワークショップガイドのご利用をお勧めします。ご不明な点などございましたら、お問い合わせフォームよりご連絡ください。 また、GitHubにて問題を報告することもできます。


Have questions? Let us know how we can help.

Contact Us

TiDB Cloud Dedicated

TiDB Cloudのエンタープライズ版。
専用VPC上に構築された専有DBaaSでAWSとGoogle Cloudで利用可能。

TiDB Cloud Serverless

TiDB Cloudのライト版。
TiDBの機能をフルマネージド環境で使用でき無料かつお客様の裁量で利用開始。