悲観的モードでのシャードテーブルからのデータのマージと移行

このドキュメントでは、悲観的モード (デフォルト モード) でデータ移行 (DM) によって提供されるシャーディング サポート機能を紹介します。この機能を使用すると、アップストリームの MySQL または MariaDB インスタンスにある同じテーブル スキーマを持つテーブルのデータを、ダウンストリーム TiDB の 1 つの同じテーブルにマージおよび移行できます。

制限

DM には、悲観的モードで次のシャーディング DDL 使用制限があります。

  • 論理シャーディング グループ(マージして 1 つの同じダウンストリーム テーブルに移行する必要があるすべてのシャーディング テーブルで構成される) の場合、移行を実行するためにシャーディング テーブルのソースを正確に含む 1 つのタスクを使用するように制限されます。
  • 論理シャーディング グループでは、上流のすべてのシャーディング テーブルで同じ DDL ステートメントを同じ順序で実行する必要があり (スキーマ名とテーブル名は異なる場合があります)、現在の DDL 操作が完全に終了しない限り、次の DDL ステートメントは実行できません。終了した。
    • たとえば、 column B追加する前にcolumn Aからtable_1追加する場合、 column A追加する前にcolumn Bからtable_2を追加することはできません。異なる順序での DDL ステートメントの実行はサポートされていません。
  • シャーディング グループでは、対応する DDL ステートメントが上流のすべてのシャーディング テーブルで実行される必要があります。
    • たとえば、 DM-worker-2に対応する 1 つ以上のアップストリーム シャード テーブルで DDL ステートメントが実行されていない場合、DDL ステートメントを実行した他の DM ワーカーは移行タスクを一時停止し、アップストリーム DDL ステートメントを受信するDM-worker-2を待ちます。
  • シャーディング グループ移行タスクはDROP DATABASE DROP TABLEサポートしません。
    • DM-worker の同期ユニットは、上流のシャードテーブルのDROP DATABASE / DROP TABLEステートメントを自動的に無視します。
  • シャーディング グループ移行タスクはTRUNCATE TABLEをサポートしていません。
    • DM-worker の同期ユニットは、上流のシャードテーブルのTRUNCATE TABLEステートメントを自動的に無視します。
  • シャーディング グループ移行タスクはRENAME TABLEをサポートしますが、次の制限があります (オンライン DDL は別のソリューションでサポートされています)。
    • テーブルの名前は、他のテーブルで使用されていない新しい名前にのみ変更できます。
    • 1 つのRENAME TABLEステートメントには 1 つのRENAME操作のみを含めることができます。
  • シャーディング グループの移行タスクでは、各 DDL ステートメントに 1 つのテーブルのみに対する操作が含まれる必要があります。
  • 各シャード テーブルのテーブル スキーマは、増分レプリケーション タスクの開始時点では同じである必要があります。これは、異なるシャード テーブルの DML ステートメントを、明確なテーブル スキーマと後続のシャーディング DDL を使用してダウンストリームに移行できるようにするためです。ステートメントを正しく照合して移行できます。
  • テーブルルーティングルールを変更する必要がある場合は、すべてのシャーディング DDL ステートメントの移行が完了するまで待つ必要があります。
    • シャーディング DDL ステートメントの移行中に、 dmctlを使用してrouter-rulesを変更すると、エラーが報告されます。
  • DDL ステートメントが実行されているシャーディング グループにCREATEテーブルを追加する必要がある場合は、テーブル スキーマが新しく変更されたテーブル スキーマと同じであることを確認する必要があります。
    • たとえば、元のtable_1table_2は両方とも、最初は 2 つの列 (a、b) があり、シャーディング DDL 操作後には 3 つの列 (a、b、c) があるため、移行後に新しく作成されたテーブルにも 3 つの列が必要になります ( a、b、c)。
  • DDL ステートメントを受信した DM ワーカーはタスクを一時停止して、他の DM ワーカーが DDL ステートメントを受信するのを待つため、データ移行の遅延が増加します。

背景

現在、DM はROW形式のbinlogを使用して移行タスクを実行します。 binlog にはテーブル スキーマ情報は含まれません。 ROWbinlogを使用してデータを移行する場合、複数のアップストリーム テーブルを同じダウンストリーム テーブルに移行していない場合、ダウンストリーム テーブルのテーブル スキーマを更新できる 1 つのアップストリーム テーブルの DDL 操作のみが存在します。 ROW binlog は自己記述の性質を持っていると考えることができます。移行プロセス中に、列の値とダウンストリーム テーブル スキーマに応じて DML ステートメントを構築できます。

ただし、シャード テーブルのマージおよび移行のプロセスで、テーブル スキーマを変更するために上流テーブルで DDL ステートメントが実行される場合は、生成される DML ステートメント間の不整合を避けるために、DDL ステートメントを移行するための追加の操作を実行する必要があります。列の値と実際のダウンストリーム テーブル スキーマによって異なります。

簡単な例を次に示します。

shard-ddl-example-1

上記の例では、マージ プロセスが簡略化されており、上流に MySQL インスタンスが 2 つだけ存在し、各インスタンスにはテーブルが 1 つだけあります。移行が開始されると、2 つのシャード テーブルのテーブル スキーマ バージョンはschema V1としてマークされ、DDL ステートメントの実行後のテーブル スキーマ バージョンはschema V2としてマークされます。

ここで、移行プロセスにおいて、2 つの上流のシャード テーブルから受信したbinlogデータの時系列が次のとおりであると仮定します。

  1. 移行が開始されると、DM ワーカーの同期ユニットは 2 つのシャード テーブルから DML イベントschema V1を受信します。
  2. t1では、インスタンス 1 からのシャーディング DDL イベントが受信されます。
  3. t2以降、同期ユニットはインスタンス 1 からschema V2の DML イベントを受信します。ただし、インスタンス 2 からは、引き続きschema V1の DML イベントを受信します。
  4. t3で、インスタンス 2 からシャーディング DDL イベントを受信します。
  5. t4以降、同期ユニットはインスタンス 2 からschema V2の DML イベントも受信します。

シャードテーブルの DDL ステートメントは、移行プロセス中に処理されないと仮定します。インスタンス 1 の DDL ステートメントがダウンストリームに移行された後、ダウンストリーム テーブル スキーマはschema V2に変更されます。しかし、インスタンス 2 の場合、DM-worker の同期ユニットはまだt2からt3までのschema V1の DML イベントを受信して​​います。したがって、 schema V1の DML ステートメントをダウンストリームに移行すると、DML ステートメントとテーブル スキーマの不一致によりエラーが発生し、データが正常に移行されない可能性があります。

原則

このセクションでは、悲観的モードでの上記の例に基づいて、シャード テーブルをマージするプロセスで DM が DDL ステートメントを移行する方法を示します。

shard-ddl-flow

この例では、 DM-worker-1 MySQL インスタンス 1 からデータを移行し、 DM-worker-2 MySQL インスタンス 2 からデータを移行しますDM-masterは複数の DM ワーカー間の DDL 移行を調整します。 DDL ステートメントを受信するDM-worker-1以降、DDL 移行プロセスは次のように簡素化されます。

  1. DM-worker-1 t1で MySQL インスタンス 1 から DDL ステートメントを受信し、対応する DDL および DML ステートメントのデータ移行を一時停止し、DDL 情報をDM-masterに送信します。
  2. DM-master 、受信した DDL 情報に基づいてこの DDL ステートメントの移行を調整する必要があると判断し、この DDL ステートメントのロックを作成し、DDL ロック情報をDM-worker-1に送り返し、同時にDM-worker-1をこのロックの所有者としてマークします。
  3. DM-worker-2 t3で MySQL インスタンス 2 から DDL ステートメントを受信し、この DDL ステートメントのデータ移行を一時停止し、DDL 情報をDM-masterに送信するまで DML ステートメントの移行を続けます。
  4. DM-master受信した DDL 情報に基づいて、この DDL ステートメントのロックがすでに存在すると判断し、ロック情報を直接DM-worker-2に送信します。
  5. タスク開始時の構成情報、上流の MySQL インスタンス内のシャード テーブル情報、およびデプロイメント トポロジ情報に基づいて、 DM-masterはマージ対象となるすべての上流のシャード テーブルのこの DDL ステートメントを受信したと判断し、 DDL ロック ( DM-worker-1 ) を使用して、この DDL ステートメントをダウンストリームに移行します。
  6. DM-worker-1ステップ #2 で受信した DDL ロック情報に基づいて DDL ステートメントの実行要求を検証し、この DDL ステートメントを下流に移行し、結果をDM-masterに送信します。この操作が成功すると、 DM-worker-1後続の ( t2binlogから開始して) DML ステートメントの移行を続行します。
  7. DM-master DDL が正常に実行されたというロック所有者からの応答を受信し、DDL ロックを待機している他のすべての DM ワーカー ( DM-worker-2 ) に、この DDL ステートメントを無視して、後続の (binlogから開始して) 移行を続行するように要求します。 t4 ) DML ステートメント。

複数の DM ワーカー間のシャーディング DDL 移行を処理する DM の特性は、次のように結論付けることができます。

  • タスク構成と DM クラスター展開トポロジー情報に基づいて、DDL 移行を調整するために論理シャーディング グループがDM-masterに構築されます。グループのメンバーは、移行タスクから分割された各サブタスクを処理する DM ワーカーです)。
  • binlogイベントから DDL ステートメントを受信した後、各 DM ワーカーは DDL 情報をDM-masterに送信します。
  • DM-master各 DM ワーカーから受信した DDL 情報とシャーディング グループ情報に基づいて DDL ロックを作成または更新します。
  • シャーディング グループのすべてのメンバーが同じ特定の DDL ステートメントを受信した場合、上流のシャーディング テーブルでの DDL 実行前のすべての DML ステートメントが完全に移行されており、この DDL ステートメントを実行できることを示します。その後、DM は後続の DML ステートメントの移行を続行できます。
  • テーブルルーターによって変換された後、アップストリームのシャードテーブルの DDL ステートメントは、ダウンストリームで実行される DDL ステートメントと一致している必要があります。したがって、この DDL ステートメントは DDL 所有者によって 1 回実行されるだけで済み、他のすべての DM ワーカーはこの DDL ステートメントを無視できます。

上記の例では、各 DM ワーカーに対応する上流の MySQL インスタンスでシャード テーブルを 1 つだけマージする必要があります。ただし、実際のシナリオでは、複数のシャード スキーマに複数のシャード テーブルがあり、1 つの MySQL インスタンスにマージされる可能性があります。これが発生すると、シャーディング DDL 移行の調整がより複雑になります。

1 つの MySQL インスタンスにマージされる 2 つのシャード テーブル ( table_1table_2があると仮定します。

shard-ddl-example-2

データは同じ MySQL インスタンスから取得されるため、すべてのデータは同じbinlogストリームから取得されます。この場合、時系列は次のようになります。

  1. DM-worker の同期ユニットは、移行の開始時に両方のシャード テーブルからschema V1の DML ステートメントを受け取ります。
  2. t1で、DM-worker の同期ユニットはtable_1の DDL ステートメントを受け取ります。
  3. t2からt3まで、受信データにはschema V2からtable_1の DML ステートメントとschema V1からtable_2の DML ステートメントが含まれます。
  4. t3で、DM-worker の同期ユニットはtable_2の DDL ステートメントを受け取ります。
  5. t4以降、DM-worker の同期ユニットは両方のテーブルからschema V2の DML ステートメントを受け取ります。

データ移行時に特にDDL文が処理されていない場合、 table_1のDDL文を下流に移行して下流のテーブルスキーマを変更する際に、 table_2からschema V1のDML文が正常に移行できません。したがって、単一の DM ワーカー内で、このグループのメンバーが同じ上流 MySQL インスタンス内の異なるシャーディング テーブルであることを除いて、 DM-master内の論理シャーディング グループと同様の論理シャーディング グループが作成されます。

ただし、DM ワーカーがその内部でシャーディング グループの移行を調整する場合、それはDM-masterによって実行されるものと完全に同じではありません。その理由は次のとおりです。

  • DM ワーカーがtable_1の DDL ステートメントを受信すると、移行を一時停止できず、後続の DDL ステートメントtable_2を取得するためにbinlogの解析を続行する必要があります。これは、 t2からt3の間で解析を続ける必要があることを意味します。
  • t2t3の間のbinlog解析プロセス中に、シャーディング DDL ステートメントが移行されて正常に実行されるまで、 schema V2からtable_1の DML ステートメントをダウンストリームに移行することはできません。

DM では、DM ワーカー内で DDL ステートメントをシャーディングする簡略化された移行プロセスは次のとおりです。

  1. DM ワーカーはt1table_1の DDL ステートメントを受信すると、DDL 情報とbinlogの現在の位置を記録します。
  2. DM ワーカーはt2からt3までのbinlogの解析を続けます。
  3. DM-worker は、 table_1に属するschema V2スキーマを持つ DML ステートメントを無視し、 table_2に属するschema V1スキーマを持つ DML ステートメントをダウンストリームに移行します。
  4. DM ワーカーはt3table_2の DDL ステートメントを受信すると、DDL 情報とbinlogの現在の位置を記録します。
  5. 移行タスクの構成と上流のスキーマとテーブルの情報に基づいて、DM ワーカーは、MySQL インスタンス内のすべてのシャード化テーブルの DDL ステートメントが受信されたと判断し、それらをダウンストリームに移行して、ダウンストリーム テーブルのスキーマを変更します。
  6. DM-worker は、新しいbinlogストリームの解析の開始点を、ステップ #1 で保存された位置に設定します。
  7. DM ワーカーはt2t3の間でbinlogの解析を再開します。
  8. DM ワーカーは、 table_1に属するschema V2スキーマを持つ DML ステートメントをダウンストリームに移行し、 table_2に属するschema V1スキーマを持つ DML ステートメントを無視します。
  9. ステップ #4 で保存されたbinlogの位置を解析した後、DM ワーカーは、ステップ #3 で無視されたすべての DML ステートメントが再びダウンストリームに移行されたと判断します。
  10. DM ワーカーは、binlogの位置t4から移行を再開します。

上記の分析から、DM はシャーディング DDL の移行を処理する際の調整と制御のために主に 2 レベルのシャーディング グループを使用すると結論付けることができます。簡略化されたプロセスは次のとおりです。

  1. 各 DM ワーカーは、上流の MySQL インスタンス内の複数のシャーディング テーブルで構成される対応するシャーディング グループの DDL ステートメントの移行を個別に調整します。
  2. DM ワーカーは、すべてのシャード テーブルの DDL ステートメントを受信した後、DDL 情報をDM-masterに送信します。
  3. DM-master受信した DDL 情報に基づいて、DM ワーカーで構成されるシャーディング グループの DDL 移行を調整します。
  4. すべての DM ワーカーから DDL 情報を受信した後、 DM-masterは DDL ロック所有者 (特定の DM ワーカー) に DDL ステートメントの実行を要求します。
  5. DDL ロック所有者は DDL ステートメントを実行し、結果をDM-masterに返します。その後、所有者は、DDL 移行の内部調整中に、以前に無視された DML ステートメントの移行を再開します。
  6. DM-masterは、所有者が DDL ステートメントを正常に実行したことを確認した後、他のすべての DM ワーカーに移行を続行するように要求します。
  7. 他のすべての DM ワーカーは、DDL 移行の内部調整中に、以前に無視された DML ステートメントの移行を個別に再開します。
  8. 無視された DML ステートメントの再度の移行が完了すると、すべての DM ワーカーは通常の移行プロセスを再開します。

このページは役に立ちましたか?