シャード マージ シナリオでのデータ移行のベスト プラクティス

このドキュメントでは、シャード マージ シナリオにおけるTiDB データ移行 (DM) の機能と制限について説明し、アプリケーションのデータ移行のベスト プラクティス ガイドを提供します (デフォルトの「ペシミスティック」モードが使用されます)。

別のデータ移行タスクを使用する

シャード テーブルからのデータのマージと移行番目のドキュメントでは、「シャーディング グループ」の定義が示されています。シャーディング グループは、マージして同じダウンストリーム テーブルに移行する必要があるすべてのアップストリーム テーブルで構成されます。

現在のシャーディング DDL メカニズムには、さまざまなシャード テーブルでの DDL 操作によってもたらされるスキーマの変更を調整するための機能がいくつかあり利用制限 。予期しない理由でこれらの制限に違反した場合は、データ移行タスク全体をDM でシャーディング DDL ロックを手動で処理する実行するか、やり直す必要があります。

例外が発生した場合のデータ移行への影響を軽減するには、各シャーディング グループを個別のデータ移行タスクとしてマージおよび移行することをお勧めします。これにより、少数のデータ移行タスクのみを手動で処理する必要があり、他のタスクは影響を受けないままにすることができます。

シャーディング DDL ロックを手動で処理する

DM のシャーディング DDL ロックは、アップストリームの複数のシャード テーブルからダウンストリームへの DDL 操作の実行を調整するためのメカニズムであることは、 シャード テーブルからのデータのマージと移行から簡単に結論付けることができます。

したがって、コマンドDM-mastershard-ddl-lockでシャーディング DDL ロックが検出された場合、または一部の DM-worker でコマンドquery-statusからunresolvedGroupsまたはblockingDDLsが検出された場合は、急いでshard-ddl-lock unlockコマンドを使用してシャーディング DDL ロックを手動で解放しないでください。

代わりに、次のことができます。

  • シャーディング DDL ロックの自動解放の失敗が 1 の列挙された異常なシナリオつである場合は、対応する手動の解決策に従ってシナリオを処理します。
  • サポートされていないシナリオの場合は、データ移行タスク全体をやり直します。まず、ダウンストリーム データベースのデータと、移行タスクに関連付けられたdm_metaの情報を空にします。次に、完全および増分データ複製を再実行します。

複数のシャード テーブル間で主キーまたは一意のインデックス間の競合を処理する

複数のシャード テーブルからのデータは、主キーまたは一意のインデックス間で競合を引き起こす可能性があります。これらのシャード テーブルのシャーディング ロジックに基づいて、各主キーまたは一意のインデックスを確認する必要があります。主キーまたは一意のインデックスに関連する 3 つのケースを次に示します。

  • シャード キー: 通常、同じシャード キーは 1 つのシャード テーブルにのみ存在します。つまり、シャード キーでデータの競合は発生しません。
  • 自動インクリメント主キー: 各シャード テーブルの自動インクリメント主キーは個別にカウントされるため、それらの範囲が重複する可能性があります。この場合、次のセクション自動インクリメント主キーの競合を処理するを参照して解決する必要があります。
  • その他の主キーまたは一意のインデックス: ビジネス ロジックに基づいて分析する必要があります。データが競合する場合は、次のセクション自動インクリメント主キーの競合を処理するを参照して解決することもできます。

自動インクリメント主キーの競合を処理する

このセクションでは、自動インクリメント主キーの競合を処理するための 2 つの推奨ソリューションを紹介します。

列からPRIMARY KEY属性を削除します

上流のスキーマが次のとおりであるとします。

CREATE TABLE `tbl_no_pk` ( `auto_pk_c1` bigint(20) NOT NULL, `uk_c2` bigint(20) NOT NULL, `content_c3` text, PRIMARY KEY (`auto_pk_c1`), UNIQUE KEY `uk_c2` (`uk_c2`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1

次の要件が満たされている場合:

  • auto_pk_c1列はアプリケーションに影響を与えず、列のPRIMARY KEY属性に依存しません。
  • uk_c2列にはUNIQUE KEY属性があり、上流のすべてのシャード テーブルでグローバルに一意です。

次に、次の手順を実行して、シャード テーブルをマージするときにauto_pk_c1列が原因である可能性があるERROR 1062 (23000): Duplicate entry '***' for key 'PRIMARY'のエラーを修正できます。

  1. 完全なデータ移行の前に、ダウンストリーム データベースにデータのマージと移行用のテーブルを作成し、 auto_pk_c1列のPRIMARY KEY属性を通常のインデックスに変更します。

    CREATE TABLE `tbl_no_pk_2` ( `auto_pk_c1` bigint(20) NOT NULL, `uk_c2` bigint(20) NOT NULL, `content_c3` text, INDEX (`auto_pk_c1`), UNIQUE KEY `uk_c2` (`uk_c2`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1
  2. 次の構成をtask.yamlに追加して、自動インクリメント主キーの競合のチェックをスキップします。

    ignore-checking-items: ["auto_increment_ID"]
  3. 完全および増分データ複製タスクを開始します。

  4. query-statusを実行して、データ移行タスクが正常に処理されたかどうか、および上流のデータが既にマージされて下流のデータベースに移行されているかどうかを確認します。

複合主キーを使用する

上流のスキーマが次のとおりであるとします。

CREATE TABLE `tbl_multi_pk` ( `auto_pk_c1` bigint(20) NOT NULL, `uuid_c2` bigint(20) NOT NULL, `content_c3` text, PRIMARY KEY (`auto_pk_c1`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1

次の要件が満たされている場合:

  • アプリケーションは、 auto_pk_c1列のPRIMARY KEY属性に依存しません。
  • auto_pk_c1列とuuid_c2列で構成される複合主キーは、グローバルに一意です。
  • アプリケーションで複合主キーを使用することは許容されます。

次に、次の手順を実行して、シャード テーブルをマージするときにauto_pk_c1列が原因である可能性があるERROR 1062 (23000): Duplicate entry '***' for key 'PRIMARY'のエラーを修正できます。

  1. 完全なデータ移行の前に、データのマージと移行のためにダウンストリーム データベースにテーブルを作成します。 auto_pk_c1列にはPRIMARY KEY属性を指定せず、 auto_pk_c1列とuuid_c2列を使用して複合主キーを構成します。

    CREATE TABLE `tbl_multi_pk_c2` ( `auto_pk_c1` bigint(20) NOT NULL, `uuid_c2` bigint(20) NOT NULL, `content_c3` text, PRIMARY KEY (`auto_pk_c1`,`uuid_c2`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1
  2. 完全および増分データ移行タスクを開始します。

  3. query-statusを実行して、データ移行タスクが正常に処理されたかどうか、およびアップストリームからのデータが既にマージされてダウンストリーム データベースに移行されているかどうかを確認します。

アップストリーム RDS にシャード テーブルが含まれている場合の特別な処理

アップストリーム データ ソースが RDS であり、シャード テーブルが含まれている場合、SQL クライアントに接続するときに、MySQL binlog のテーブル名が表示されないことがあります。たとえば、アップストリームが UCloud 分散データベースである場合、binlog のテーブル名には追加のプレフィックス_0001が含まれる場合があります。したがって、SQL クライアントのテーブル名ではなく、binlog のテーブル名に基づいてテーブル ルーティングを構成する必要があります。

アップストリームでのテーブルの作成/削除

シャード テーブルからのデータのマージと移行では、シャーディング DDL ロックの調整が、ダウンストリーム データベースがすべてのアップストリーム シャード テーブルの DDL ステートメントを受信するかどうかに依存することは明らかです。さらに、DM は現在、アップストリームでシャード テーブルを動的に作成または削除することをサポートしていません。したがって、アップストリームでシャード テーブルを作成または削除するには、次の手順を実行することをお勧めします。

アップストリームでシャード テーブルを作成する

アップストリームで新しいシャード テーブルを作成する必要がある場合は、次の手順を実行します。

  1. アップストリームのシャード テーブルで実行されたすべてのシャーディング DDL の調整が完了するまで待ちます。

  2. stop-taskを実行して、データ移行タスクを停止します。

  3. アップストリームに新しいシャード テーブルを作成します。

  4. task.yamlファイルの構成により、新しく追加されたシャード テーブルを 1 つのダウンストリーム テーブルで他の既存のシャード テーブルとマージできることを確認します。

  5. start-taskを実行してタスクを開始します。

  6. query-statusを実行して、データ移行タスクが正常に処理されたかどうか、およびアップストリームからのデータが既にマージされてダウンストリーム データベースに移行されているかどうかを確認します。

アップストリームに分割されたテーブルをドロップする

アップストリームでシャード テーブルを削除する必要がある場合は、次の手順を実行します。

  1. 分割されたテーブルを削除し、 SHOW BINLOG EVENTSを実行して binlog イベントのDROP TABLEステートメントに対応するEnd_log_posをフェッチし、それをPos-Mとしてマークします。

  2. query-statusを実行して、DM によって処理された binlog イベントに対応する位置 ( syncerBinlog ) をフェッチし、それをPos-Sとしてマークします。

  3. Pos-SPos-Mより大きい場合は、DM がDROP TABLEのステートメントをすべて処理したことを意味し、ドロップ前のテーブルのデータはダウンストリームに移行されているため、後続の操作を実行できます。それ以外の場合は、DM がデータの移行を完了するまで待ちます。

  4. stop-taskを実行してタスクを停止します。

  5. task.yamlファイルの構成が、アップストリームで削除されたシャード テーブルを無視していることを確認してください。

  6. start-taskを実行してタスクを開始します。

  7. query-statusを実行して、データ移行タスクが正常に処理されたかどうかを確認します。

速度制限と交通流制御

複数のアップストリーム MySQL または MariaDB インスタンスからのデータがマージされ、ダウンストリームの同じ TiDB クラスターに移行されると、各アップストリーム インスタンスに対応するすべての DM-worker が完全な増分データ レプリケーションを同時に実行します。これは、DM ワーカーの数が増えるとデフォルトの同時実行度 (完全データ移行ではpool-size 、増分データ レプリケーションではworker-count ) が累積され、ダウンストリーム データベースが過負荷になる可能性があることを意味します。この場合、TiDB と DM の監視メトリックに基づいて予備的なパフォーマンス分析を行い、各同時実行パラメーターの値を調整する必要があります。将来、DM は部分的に自動化されたトラフィック フロー制御をサポートする予定です。