ペシミスティック モードでのシャード テーブルからのデータのマージと移行
このドキュメントでは、悲観的モード (既定のモード) でデータ移行 (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 ステートメントを上流のすべてのシャード テーブルで実行する必要があります。
- たとえば、 DDL ステートメントが
DM-worker-2
に対応する 1 つ以上のアップストリーム シャード テーブルで実行されない場合、DDL ステートメントを実行した他の DM ワーカーは移行タスクを一時停止し、アップストリーム DDL ステートメントを受信するまでDM-worker-2
待ちます。
- たとえば、 DDL ステートメントが
- シャーディング グループ
DROP TABLE
移行タスクはDROP DATABASE
をサポートしていません。- DM-worker の同期ユニットは、アップストリームのシャード テーブルの
DROP DATABASE
/DROP TABLE
ステートメントを自動的に無視します。
- DM-worker の同期ユニットは、アップストリームのシャード テーブルの
- シャーディング グループの移行タスクは
TRUNCATE TABLE
をサポートしていません。- DM-worker の同期ユニットは、アップストリームのシャード テーブルの
TRUNCATE TABLE
のステートメントを自動的に無視します。
- DM-worker の同期ユニットは、アップストリームのシャード テーブルの
- シャーディング グループ移行タスクは
RENAME TABLE
をサポートしますが、次の制限があります (オンライン DDL は別のソリューションでサポートされます)。- テーブルの名前は、他のテーブルで使用されていない新しい名前にのみ変更できます。
- 単一の
RENAME TABLE
ステートメントは、単一のRENAME
操作のみを含むことができます。
- シャーディング グループの移行タスクでは、各 DDL ステートメントに 1 つのテーブルのみに対する操作を含める必要があります。
- 各シャード テーブルのテーブル スキーマは、増分レプリケーション タスクの開始時点で同じである必要があります。これにより、異なるシャード テーブルの DML ステートメントが、明確なテーブル スキーマと後続のシャーディング DDL を使用してダウンストリームに移行できるようになります。ステートメントを正しく照合して移行できます。
- テーブル ルーティングルールを変更する必要がある場合は、すべてのシャーディング DDL ステートメントの移行が完了するまで待つ必要があります。
- シャーディング DDL ステートメントの移行中に、
dmctl
を使用してrouter-rules
を変更すると、エラーが報告されます。
- シャーディング DDL ステートメントの移行中に、
- DDL ステートメントが実行されているシャーディング グループに新しいテーブルを
CREATE
する必要がある場合は、テーブル スキーマが新しく変更されたテーブル スキーマと同じであることを確認する必要があります。- たとえば、元の
table_1
とtable_2
両方に、最初は 2 つの列 (a、b) があり、シャーディング DDL 操作後は 3 つの列 (a、b、c) があるため、移行後、新しく作成されたテーブルにも 3 つの列があるはずです ( a、b、c)。
- たとえば、元の
- DDL ステートメントを受信した DM-worker はタスクを一時停止して、他の DM-worker が DDL ステートメントを受信するのを待つため、データ移行の遅延が増加します。
バックグラウンド
現在、DM はROW
形式のbinlog を使用して移行タスクを実行します。 binlog には、テーブル スキーマ情報が含まれていません。 ROW
binlogを使用してデータを移行する場合、複数のアップストリーム テーブルを同じダウンストリーム テーブルに移行していない場合、ダウンストリーム テーブルのテーブル スキーマを更新できる 1 つのアップストリーム テーブルの DDL 操作のみが存在します。 ROW
binlogは、自己記述の性質を持つと見なすことができます。移行プロセス中に、列の値とダウンストリームのテーブル スキーマに応じて DML ステートメントを作成できます。
ただし、シャードされたテーブルをマージおよび移行するプロセスで、アップストリーム テーブルで DDL ステートメントが実行されてテーブル スキーマが変更された場合、追加の操作を実行して DDL ステートメントを移行し、生成された DML ステートメント間の不整合を回避する必要があります。列の値と実際のダウンストリーム テーブル スキーマによって。
簡単な例を次に示します。
上記の例では、マージ プロセスは単純化されており、アップストリームには 2 つの MySQL インスタンスしか存在せず、各インスタンスには 1 つのテーブルしかありません。移行が開始されると、2 つのシャード テーブルのテーブル スキーマ バージョンはschema V1
としてマークされ、DDL ステートメントを実行した後のテーブル スキーマ バージョンはschema V2
としてマークされます。
ここで、移行プロセスで、上流の 2 つのシャード テーブルから受信したbinlogデータの時系列が次のようになっているとします。
- 移行が開始されると、DM-worker の同期ユニットは 2 つのシャード テーブルから
schema V1
の DML イベントを受け取ります。 t1
で、インスタンス 1 からのシャーディング DDL イベントが受信されます。t2
以降、同期ユニットはインスタンス 1 からschema V2
の DML イベントを受け取ります。ただし、インスタンス 2 からは、引き続きschema V1
の DML イベントを受け取ります。t3
で、インスタンス 2 からのシャーディング DDL イベントが受信されます。t4
以降、同期ユニットはインスタンス 2 からもschema V2
の DML イベントを受信します。
シャード テーブルの DDL ステートメントは、移行プロセス中に処理されないとします。インスタンス 1 の DDL ステートメントがダウンストリームに移行された後、ダウンストリーム テーブル スキーマはschema V2
に変更されます。しかし、インスタンス 2 の場合、DM-worker の同期ユニットはschema V1
からt2
からt3
の DML イベントをまだ受信しています。そのため、 schema V1
の DML ステートメントをダウンストリームに移行すると、DML ステートメントとテーブル スキーマの間の不整合によってエラーが発生し、データが正常に移行されない可能性があります。
原則
このセクションでは、上記の悲観的モードの例に基づいて、分割されたテーブルをマージするプロセスで DM が DDL ステートメントを移行する方法を示します。
この例では、 DM-worker-1
MySQL インスタンス 1 からデータを移行し、 DM-worker-2
MySQL インスタンス 2 からデータを移行しますDM-master
は、複数の DM ワーカー間で DDL 移行を調整します。 DDL ステートメントを受け取るDM-worker-1
から開始すると、DDL 移行プロセスは次のように簡素化されます。
DM-worker-1
t1
で MySQL インスタンス 1 から DDL ステートメントを受け取り、対応する DDL および DML ステートメントのデータ移行を一時停止し、DDL 情報をDM-master
に送信します。DM-master
、受信した DDL 情報に基づいてこの DDL ステートメントの移行を調整する必要があると判断し、この DDL ステートメントのロックを作成し、DDL ロック情報をDM-worker-1
に送り返し、同時にDM-worker-1
をこのロックの所有者としてマークします。DM-worker-2
t3
で MySQL インスタンス 2 から DDL ステートメントを受信するまで DML ステートメントの移行を続け、この DDL ステートメントのデータ移行を一時停止し、DDL 情報をDM-master
に送信します。DM-master
受信した DDL 情報に基づいて、この DDL ステートメントのロックが既に存在すると判断し、ロック情報をDM-worker-2
に直接送信します。- タスクが開始されたときの構成情報、上流の MySQL インスタンスのシャード テーブル情報、および展開トポロジ情報に基づいて、
DM-master
はマージされるすべての上流のシャード テーブルのこの DDL ステートメントを受け取ったと判断し、 DDL ロック (DM-worker-1
) を使用して、この DDL ステートメントをダウンストリームに移行します。 DM-worker-1
ステップ #2 で受け取った DDL ロック情報に基づいて DDL ステートメントの実行要求を検証し、この DDL ステートメントをダウンストリームに移行して、結果をDM-master
に送信します。この操作が成功した場合、DM-worker-1
後続の (t2
のbinlogから始まる) DML ステートメントの移行を続行します。DM-master
、DDL が正常に実行されたというロック所有者からの応答を受信し、DDL ロックを待機している他のすべての DM-worker (DM-worker-2
) に、この DDL ステートメントを無視してから、後続の移行を続行するように要求します (次のbinlogから開始)。t4
) DML ステートメント。
複数の DM-worker 間でシャーディング DDL 移行を処理する DM の特徴は、次のように結論付けることができます。
- タスク構成と DM クラスター展開トポロジー情報に基づいて、DDL 移行を調整するために論理シャーディング グループが
DM-master
に組み込まれます。グループ メンバーは、移行タスクから分割された各サブタスクを処理する DM ワーカーです)。 - binlogイベントから DDL ステートメントを受け取った後、各 DM-worker は DDL 情報を
DM-master
に送信します。 DM-master
各 DM-worker から受信した DDL 情報とシャーディング グループ情報に基づいて、DDL ロックを作成または更新します。- シャーディング グループのすべてのメンバーが同じ特定の DDL ステートメントを受け取る場合、これは、上流のシャード テーブルでの DDL 実行前のすべての DML ステートメントが完全に移行され、この DDL ステートメントを実行できることを示します。その後、DM は後続の DML ステートメントの移行を続行できます。
- テーブルルーターによって変換された後、アップストリームのシャード テーブルの DDL ステートメントは、ダウンストリームで実行される DDL ステートメントと一致している必要があります。したがって、この DDL ステートメントは DDL 所有者によって 1 回だけ実行される必要があり、他のすべての DM ワーカーはこの DDL ステートメントを無視できます。
上記の例では、各 DM-worker に対応する上流の MySQL インスタンスでマージする必要があるのは、1 つのシャード テーブルのみです。ただし、実際のシナリオでは、複数のシャード スキーマに複数のシャード テーブルが存在し、1 つの MySQL インスタンスにマージされる場合があります。これが発生すると、シャーディング DDL 移行の調整がより複雑になります。
2 つのシャード テーブル、つまりtable_1
とtable_2
が 1 つの MySQL インスタンスにマージされるとします。
データは同じ MySQL インスタンスから取得されるため、すべてのデータは同じbinlogストリームから取得されます。この場合、時系列は次のようになります。
- DM-worker の同期ユニットは、移行の開始時に両方のシャード テーブルから
schema V1
の DML ステートメントを受け取ります。 t1
で、DM-worker の同期ユニットはtable_1
の DDL ステートメントを受け取ります。- 受信したデータには、
t2
からt3
までのschema V2
からtable_1
の DML ステートメントと、schema V1
からtable_2
までの DML ステートメントが含まれます。 t3
で、DM-worker の同期ユニットはtable_2
の DDL ステートメントを受け取ります。t4
以降、DM-worker の同期ユニットは両方のテーブルからschema V2
の DML ステートメントを受け取ります。
特にデータ移行時にDDL文を処理しないと、 table_1
のDDL文を下流に移行し、下流のテーブルスキーマを変更する際に、 table_2
からschema V1
のDML文を正常に移行できません。したがって、単一の DM-worker 内で、このグループのメンバーが同じアップストリーム MySQL インスタンス内の異なるシャード テーブルであることを除いて、 DM-master
内と同様の論理シャーディング グループが作成されます。
しかし、DM-worker がシャーディング グループの移行を自分自身で調整する場合、それはDM-master
によって実行されるものと完全に同じではありません。理由は次のとおりです。
- DM-worker が
table_1
の DDL ステートメントを受け取ると、移行を一時停止できず、 binlogの解析を続行してtable_2
後続の DDL ステートメントを取得する必要があります。これは、t2
とt3
の間で解析を続ける必要があることを意味します。 t2
とt3
の間のbinlog解析プロセス中に、シャーディング DDL ステートメントが移行され、正常に実行されるまで、schema V2
からtable_1
の DML ステートメントをダウンストリームに移行することはできません。
DM では、DM ワーカー内で DDL ステートメントをシャーディングする単純化された移行プロセスは次のとおりです。
- DM-worker は
table_1
のt1
DDL ステートメントを受け取ると、DDL 情報とbinlogの現在位置を記録します。 - DM-worker は
t2
とt3
の間でbinlogの解析を続けます。 - DM-worker は、
table_1
に属するschema V2
スキーマの DML ステートメントを無視し、table_2
に属するschema V1
スキーマの DML ステートメントを下流に移行します。 - DM-worker は
table_2
のt3
DDL ステートメントを受け取ると、DDL 情報とbinlogの現在位置を記録します。 - 移行タスク構成と上流のスキーマおよびテーブルの情報に基づいて、DM ワーカーは、MySQL インスタンス内のすべてのシャード テーブルの DDL ステートメントが受信されたと判断し、それらを下流に移行して下流のテーブル スキーマを変更します。
- DM-worker は、新しいbinlogストリームの解析の開始点を、ステップ #1 で保存した位置に設定します。
- DM-worker は
t2
とt3
の間でbinlogの解析を再開します。 - DM-worker は
table_1
に属するschema V2
スキーマの DML ステートメントを下流に移行し、table_2
に属するschema V1
スキーマの DML ステートメントを無視します。 - ステップ 4 で保存されたbinlog位置を解析した後、DM ワーカーは、ステップ 3 で無視されたすべての DML ステートメントが再びダウンストリームに移行されたと判断します。
- DM-worker は、 binlog の位置
t4
から移行を再開します。
上記の分析から、DM は主に 2 レベルのシャーディング グループを使用して、シャーディング DDL の移行を処理する際の調整と制御を行うと結論付けることができます。簡単なプロセスは次のとおりです。
- 各 DM ワーカーは、アップストリーム MySQL インスタンス内の複数のシャード テーブルで構成される、対応するシャーディング グループの DDL ステートメントの移行を個別に調整します。
- DM-worker は、シャードされたすべてのテーブルの DDL ステートメントを受信した後、DDL 情報を
DM-master
に送信します。 DM-master
受信した DDL 情報に基づいて、DM ワーカーで構成されるシャーディング グループの DDL 移行を調整します。- すべての DM-worker から DDL 情報を受け取った後、
DM-master
は DDL ロックの所有者 (特定の DM-worker) に DDL ステートメントを実行するように要求します。 - DDL ロック所有者は DDL ステートメントを実行し、結果を
DM-master
に返します。次に、所有者は、DDL 移行の内部調整中に、以前に無視された DML ステートメントの移行を再開します。 DM-master
は、所有者が DDL ステートメントを正常に実行したことを確認した後、他のすべての DM ワーカーに移行を続行するように要求します。- 他のすべての DM ワーカーは、DDL 移行の内部調整中に、以前に無視された DML ステートメントの移行を個別に再開します。
- 無視された DML ステートメントの移行が再び完了すると、すべての DM ワーカーは通常の移行プロセスを再開します。