📣
TiDB Cloud Premium はパブリックプレビュー中です。エンタープライズワークロード向けの無制限のスケーリング、即時の弾力性、高度なセキュリティを提供します。このページは自動翻訳されたものです。原文はこちらからご覧ください。

悲観的モードでシャーディングされたテーブルからデータをマージおよび移行する



このドキュメントでは、データ移行(DM)の悲観的モード(デフォルトモード)で提供されるシャーディングサポート機能について説明します。この機能を使用すると、上流のMySQLまたはMariaDBインスタンスで同じテーブルスキーマを持つテーブルのデータを、下流のTiDBの同じテーブルにマージして移行できます。

制限

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

  • 論理シャーディンググループ(マージして同一のダウンストリームテーブルに移行する必要のあるすべてのシャーディングテーブルで構成される)の場合、移行を実行するために使用できるタスクは、シャーディングテーブルのソースを正確に含む1つのタスクに限定されます。
  • 論理シャーディンググループでは、すべてのアップストリームのシャーディングテーブル(スキーマ名とテーブル名は異なっていても構いません)において、同じDDL文を同じ順序で実行する必要があり、現在のDDL操作が完全に完了するまで、次のDDL文を実行することはできません。
    • 例えば、 column Atable_1に追加してからcolumn Bを追加した場合、 column Btable_2に追加してからcolumn Aを追加することはできません。DDL文を異なる順序で実行することはサポートされていません。
  • シャーディンググループでは、対応するDDL文は、すべてのアップストリームのシャーディングテーブルで実行される必要があります。
    • 例えば、 DM-worker-2に対応する 1つ以上のアップストリーム シャーディング テーブルで DDL文が実行されない場合、DDL文を実行した他の DM-worker は移行タスクを一時停止し、 DM-worker-2がアップストリーム DDL文を受信するのを待ちます。
  • シャーディンググループ移行タスクはDROP DATABASE / DROP TABLEをサポートしていません。
    • DM-worker の同期ユニットは、アップストリームのシャーディングされたテーブルのDROP DATABASE / DROP TABLE文を自動的に無視します。
  • シャーディンググループ移行タスクはTRUNCATE TABLEをサポートしていません。
    • DM-worker の同期ユニットは、アップストリームのシャーディングされたテーブルのTRUNCATE TABLE文を自動的に無視します。
  • シャーディンググループ移行タスクはRENAME TABLEをサポートしていますが、以下の制限があります(オンライン DDL は別のソリューションでサポートされています)。
    • テーブルの名前は、他のテーブルで使用されていない新しい名前にのみ変更できます。
    • 単一のRENAME TABLE文には、単一の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-workerは、他のDM-workerがDDL文を受信するまでタスクを一時停止するため、データ移行の遅延が増加します。

背景

現在、DM はROW形式のbinlogを使用して移行タスクを実行します。binlogにはテーブルスキーマ情報は含まれていません。 ROWbinlogを使用してデータを移行する場合、複数の上流テーブルを同じ下流テーブルに移行していない限り、下流テーブルのテーブルスキーマを更新できる上流テーブルの DDL 操作は 1つしか存在しません。 ROWbinlogは自己記述的な性質を持つと考えられます。移行プロセス中に、列の値と下流テーブルのスキーマに応じて DML文を構築できます。

ただし、シャーディングされたテーブルのマージと移行の過程で、テーブルスキーマを変更するために上流テーブルでDDL文が実行された場合、列の値によって生成されたDML文と実際の下流テーブルスキーマとの間の不整合を回避するために、DDL文を移行するための追加操作を実行する必要があります。

簡単な例を挙げましょう。

shard-ddl-example-1

上記の例では、マージ処理が簡略化されており、上流には 2つの MySQL インスタンスのみが存在し、各インスタンスには 1つのテーブルしかありません。移行が開始されると、2つのシャーディングされたテーブルのテーブルスキーマバージョンはschema V1とマークされ、DDL文の実行後のテーブルスキーマバージョンはschema V2とマークされます。

ここで、移行プロセスにおいて、上流の2つのシャーディングされたテーブルから受信したbinlogデータが、以下の時間シーケンスを持つと仮定します。

  1. 移行が開始されると、DM-worker の同期ユニットは、2つのシャーディングされたテーブルからschema V1の DML イベントを受信します。
  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文をどのように移行するかを示します。

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

  1. DM-worker-1t1の 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文を受信するまで DML文の移行を継続し、この DDL文のデータ移行を一時停止し、DDL 情報をDM-masterに送信します。
  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は後続の ( t2のbinlogから始まる) DML文の移行を続行します。
  7. DM-masterはロック所有者から DDL が正常に実行されたという応答を受け取り、DDL ロックを待機している他のすべての DM-worker ( DM-worker-2 ) に、この DDL文を無視し、後続の ( t4のbinlogから始まる) DML文の移行を続行するようにリクエストします。

複数のDM-worker間でシャーディングDDL移行を処理するDMの特性は、以下のようにまとめられます。

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

上記の例では、各DM-workerに対応するアップストリームのMySQLインスタンスでマージする必要があるのは、シャーディングされたテーブル1つだけです。しかし、実際のシナリオでは、複数のシャーディングされたスキーマに複数のシャーディングされたテーブルが存在し、それらを1つのMySQLインスタンスでマージする必要がある場合があります。このような場合、シャーディングDDLの移行を調整するのがより複雑になります。

table_1table_2という 2つのシャーディングされたテーブルを、1つの MySQL インスタンスにマージすると仮定します。

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文がダウンストリームに移行され、ダウンストリームのテーブルスキーマが変更されると、 schema V1からのtable_2のDML文は正常に移行されません。そのため、単一のDM-worker内で、 DM-master内のものと同様の論理シャーディンググループが作成されますが、このグループのメンバーは、同じアップストリームMySQLインスタンス内の異なるシャーディングテーブルになります。

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

  • DM-worker がtable_1の DDL文を受信すると、移行を一時停止することはできず、binlogの解析を続行して、後続のtable_2の DDL文を取得する必要があります。つまりt2t3の間の解析を続行する必要があります。
  • t2t3間のbinlog解析処理中、シャーディング DDL文が移行され、正常に実行されるまで、 schema V2table_1の DML文はダウンストリームに移行できません。

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

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

上記の分析から、DMはシャーディングDDLの移行処理において、調整と制御のために主に2レベルのシャーディンググループを使用していることがわかります。以下に簡略化したプロセスを示します。

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

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