DMでシャーディングDDLロックを手動で処理する
DMは、シャーディングDDLロックを使用して、操作が正しい順序で実行されるようにします。このロックメカニズムは、ほとんどの場合、シャーディングDDLロックを自動的に解決しますが、一部の異常なシナリオでは、 unlock-ddl-lock
コマンドを使用して異常なDDLロックを手動で処理する必要があります。
ノート:
- このドキュメントは、ペシミスティックコーディネーションモードでのシャーディングDDLロックの処理にのみ適用されます。
- このドキュメントの「コマンドの使用法」セクションのコマンドは、対話型モードです。コマンドラインモードでは、エラーレポートを回避するために、エスケープ文字を追加する必要があります。
- コマンドによってもたらされる可能性のある影響を完全に認識していて、それらを受け入れることができる場合を除いて、
unlock-ddl-lock
またはbreak-ddl-lock
を使用しないでください。- 異常なDDLロックを手動で処理する前に、 シャードマージの原則をすでに読んでいることを確認してください。
指示
show-ddl-locks
このコマンドは、 DM-master
の現在のDDLロック情報を照会します。
コマンドの使用法
show-ddl-locks [--source=mysql-replica-01] [task-name | task-file]
引数の説明
source
:- 国旗;ストリング;
--source
;オプション - 複数回繰り返し指定できます。
- 指定されていない場合、このコマンドはすべてのMySQLソースに関連するロック情報を照会します。指定されている場合、このコマンドは、指定されたMySQLソースにのみ関連するロック情報を照会します。
- 国旗;ストリング;
task-name | task-file
:- 非フラグ;ストリング;オプション
- 指定されていない場合、このコマンドはすべてのタスクに関連するロック情報を照会します。指定されている場合、このコマンドは、指定されたタスクにのみ関連するロック情報を照会します。
結果の例
» show-ddl-locks test
{
"result": true, # The result of the query for the lock information.
"msg": "", # The additional message for the failure to query the lock information or other descriptive information (for example, the lock task does not exist).
"locks": [ # The existing lock information list.
{
"ID": "test-`shard_db`.`shard_table`", # The lock ID, which is made up of the current task name and the schema/table information corresponding to the DDL.
"task": "test", # The name of the task to which the lock belongs.
"mode": "pessimistic" # The shard DDL mode. Can be set to "pessimistic" or "optimistic".
"owner": "mysql-replica-01", # The owner of the lock (the ID of the first source that encounters this DDL operation in the pessimistic mode), which is always empty in the optimistic mode.
"DDLs": [ # The list of DDL operations corresponding to the lock in the pessimistic mode, which is always empty in the optimistic mode.
"USE `shard_db`; ALTER TABLE `shard_db`.`shard_table` DROP COLUMN `c2`;"
],
"synced": [ # The list of sources that have received all sharding DDL events in the corresponding MySQL instance.
"mysql-replica-01"
],
"unsynced": [ # The list of sources that have not yet received all sharding DDL events in the corresponding MySQL instance.
"mysql-replica-02"
]
}
]
}
unlock-ddl-lock
このコマンドは、所有者にDDLステートメントの実行を要求し、所有者ではない他のすべてのDMワーカーにDDLステートメントをスキップするように要求し、 DM-master
のロック情報を削除するなど、指定されたDDLロックのロックを解除するようにDM-master
をアクティブに要求します。
ノート:
現在、
unlock DDL lock
はpessimistic
モードのロックに対してのみ有効です。
コマンドの使用法
unlock-ddl-lock [--owner] [--force-remove] <lock-ID>
引数の説明
owner
:- 国旗;ストリング;
--owner
;オプション - 指定されていない場合、このコマンドはデフォルトの所有者(
show-ddl-locks
の結果の所有者)にDDLステートメントの実行を要求します。指定されている場合、このコマンドはMySQLソース(デフォルトの所有者の代替)にDDLステートメントの実行を要求します。 - 元の所有者がクラスタから既に削除されていない限り、新しい所有者を指定しないでください。
- 国旗;ストリング;
force-remove
:- 国旗;ブール値;
--force-remove
;オプション - 指定されていない場合、このコマンドは、所有者がDDLステートメントの実行に成功した場合にのみロック情報を削除します。指定されている場合、このコマンドは、所有者がDDLステートメントの実行に失敗した場合でも、ロック情報を強制的に削除します(これを実行した後は、ロックを再度照会したり操作したりすることはできません)。
- 国旗;ブール値;
lock-ID
:- 非フラグ;ストリング;必要
- ロックを解除する必要のあるDDLロックのIDを指定します(
show-ddl-locks
の結果のID
)。
結果の例
» unlock-ddl-lock test-`shard_db`.`shard_table`
{
"result": true, # The result of the unlocking operation.
"msg": "", # The additional message for the failure to unlock the lock.
}
サポートされているシナリオ
現在、 unlock-ddl-lock
コマンドは、次の2つの異常なシナリオでのシャーディングDDLロックの処理のみをサポートしています。
シナリオ1:一部のMySQLソースが削除されます
異常なロックの理由
DM-master
がシャーディングDDLロックのロックを自動的に解除しようとする前に、すべてのMySQLソースがシャーディングDDLイベントを受信する必要があります(詳細については、 シャードマージの原則を参照してください)。シャーディングDDLイベントがすでに移行プロセスにあり、一部のMySQLソースが削除されて再ロードされない場合(これらのMySQLソースはアプリケーションの要求に応じて削除されます)、シャーディングDDLロックを自動的に移行およびロック解除することはできません。すべてのDMワーカーがDDLイベントを受信できるわけではないためです。
ノート:
シャーディングDDLイベントを移行していないときに、一部のDMワーカーをオフラインにする必要がある場合は、
stop-task
を使用して実行中のタスクを最初に停止し、DMワーカーをオフラインにし、対応する構成情報をから削除することをお勧めします。タスク構成ファイルを作成し、最後にstart-task
と新しいタスク構成を使用して移行タスクを再開します。
手動ソリューション
アップストリームに2つのインスタンスMySQL-1
( mysql-replica-01
)とMySQL-2
( mysql-replica-02
)があり、2つのテーブルshard_db_1
があるとします。 shard_table_1
とshard_db_1
。 MySQL-1
のshard_table_2
と2つのテーブルshard_db_2
。 shard_table_1
とshard_db_2
。 MySQL-2
のshard_table_2
。次に、4つのテーブルをマージし、それらをテーブルshard_db
に移行する必要があります。ダウンストリームTiDBでshard_table
。
初期のテーブル構造は次のとおりです。
SHOW CREATE TABLE shard_db_1.shard_table_1;
+---------------+------------------------------------------+
| Table | Create Table |
+---------------+------------------------------------------+
| shard_table_1 | CREATE TABLE `shard_table_1` (
`c1` int(11) NOT NULL,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+---------------+------------------------------------------+
次のDDL操作は、テーブル構造を変更するためにアップストリームのシャーディングされたテーブルで実行されます。
ALTER TABLE shard_db_*.shard_table_* ADD COLUMN c2 INT;
MySQLとDMの操作プロセスは次のとおりです。
対応するDDL操作は、テーブル構造を変更するために
mysql-replica-01
の2つのシャーディングされたテーブルで実行されます。ALTER TABLE shard_db_1.shard_table_1 ADD COLUMN c2 INT;ALTER TABLE shard_db_1.shard_table_2 ADD COLUMN c2 INT;DM-workerは、
mysql-replica-01
の2つのシャーディングテーブルの受信したDDL情報をDM-masterに送信し、DM-masterは対応するDDLロックを作成します。show-ddl-lock
を使用して、現在のDDLロックの情報を確認します。» show-ddl-locks test { "result": true, "msg": "", "locks": [ { "ID": "test-`shard_db`.`shard_table`", "task": "test", "mode": "pessimistic" "owner": "mysql-replica-01", "DDLs": [ "USE `shard_db`; ALTER TABLE `shard_db`.`shard_table` ADD COLUMN `c2` int(11);" ], "synced": [ "mysql-replica-01" ], "unsynced": [ "mysql-replica-02" ] } ] }アプリケーションの需要により、
mysql-replica-02
に対応するデータをダウンストリームTiDBに移行する必要がなくなり、mysql-replica-02
が削除されます。IDが
test-`shard_db`.`shard_table`
対DM-master
のロックは、mysql-replica-02
のDDL情報を受信できません。- 返される結果
unsynced
には、常にshow-ddl-locks
の情報が含まれていmysql-replica-02
。
- 返される結果
unlock-dll-lock
を使用してDM-master
に要求し、DDLロックをアクティブにロック解除します。DDLロックの所有者がオフラインになった場合は、パラメーター
--owner
を使用して、DDLを実行するための新しい所有者として別のDMワーカーを指定できます。いずれかのMySQLソースがエラーを報告した場合、
result
はfalse
に設定されます。この時点で、各MySQLソースのエラーが許容可能であり、期待範囲内であるかどうかを注意深く確認する必要があります。unlock-ddl-lock test-`shard_db`.`shard_table`{ "result": true, "msg": ""
show-ddl-locks
を使用して、DDLロックが正常にロック解除されているかどうかを確認します。» show-ddl-locks test { "result": true, "msg": "no DDL lock exists", "locks": [ ] }ダウンストリームTiDBでテーブル構造が正常に変更されているかどうかを確認します。
mysql> SHOW CREATE TABLE shard_db.shard_table; +-------------+--------------------------------------------------+ | Table | Create Table | +-------------+--------------------------------------------------+ | shard_table | CREATE TABLE `shard_table` ( `c1` int(11) NOT NULL, `c2` int(11) DEFAULT NULL, PRIMARY KEY (`c1`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin | +-------------+--------------------------------------------------+query-status
を使用して、移行タスクが正常かどうかを確認します。
影響
unlock-ddl-lock
を使用して手動でロックのロックを解除した後、タスク構成情報に含まれるオフラインのMySQLソースを処理しないと、次のシャーディングDDLイベントを受信したときにロックを自動的に移行できない場合があります。
したがって、DDLロックを手動でロック解除した後、次の操作を実行する必要があります。
stop-task
を使用して、実行中のタスクを停止します。- タスク構成ファイルを更新し、オフラインMySQLソースの関連情報を構成ファイルから削除します。
start-task
と新しいタスク構成ファイルを使用して、タスクを再開します。
ノート:
unlock-ddl-lock
を実行した後、オフラインになったMySQLソースがリロードされ、DMワーカーがシャーディングされたテーブルのデータを移行しようとすると、データとダウンストリームテーブル構造の間で一致エラーが発生する可能性があります。
シナリオ2:一部のDMワーカーが異常に停止するか、DDLロック解除プロセス中にネットワーク障害が発生します
異常なロックの理由
DM-master
がすべてのDMワーカーのDDLイベントを受信した後、自動的に実行されるunlock DDL lock
には、主に次の手順が含まれます。
- ロックの所有者にDDLを実行し、対応するシャードテーブルのチェックポイントを更新するように依頼します。
- 所有者がDDLを正常に実行した後、
DM-master
に格納されているDDLロック情報を削除します。 - 所有者がDDLを正常に実行した後、他のすべての非所有者にDDLをスキップし、対応するシャードテーブルのチェックポイントを更新するように依頼します。
- DM-masterは、すべての所有者または非所有者の操作が成功した後、対応するDDLロック情報を削除します。
現在、上記のロック解除プロセスはアトミックではありません。非所有者がDDL操作を正常にスキップすると、非所有者がいるDMワーカーが異常に停止するか、ダウンストリームTiDBでネットワーク異常が発生し、チェックポイントの更新が失敗する可能性があります。
非所有者に対応するMySQLソースがデータ移行を復元すると、非所有者は、例外が発生する前に調整されたDDL操作を再調整するようにDMマスターに要求しようとし、他から対応するDDL操作を受信することはありません。 MySQLソース。これにより、DDL操作で対応するロックが自動的にロック解除される可能性があります。
手動ソリューション
これで、 一部のMySQLソースが削除されましたの手動ソリューションと同じアップストリームとダウンストリームのテーブル構造があり、テーブルのマージと移行に対する需要が同じであると仮定します。
DM-master
が自動的にロック解除プロセスを実行すると、所有者( mysql-replica-01
)はDDLを正常に実行し、移行プロセスを続行します。ただし、非所有者( mysql-replica-02
)にDDL操作のスキップを要求するプロセスでは、対応するDM-workerが再起動されたため、DM-workerがDDL操作をスキップした後、チェックポイントの更新に失敗します。
mysql-replica-02
の復元に対応するデータ移行サブタスクの後、DMマスターに新しいロックが作成されますが、他のMySQLソースがDDL操作を実行またはスキップし、後続の移行を実行しています。
操作プロセスは次のとおりです。
show-ddl-locks
を使用して、対応するDDLのロックがDM-master
に存在するかどうかを確認します。synced
状態にあるのはmysql-replica-02
つだけです。» show-ddl-locks { "result": true, "msg": "", "locks": [ { "ID": "test-`shard_db`.`shard_table`", "task": "test", "mode": "pessimistic" "owner": "mysql-replica-02", "DDLs": [ "USE `shard_db`; ALTER TABLE `shard_db`.`shard_table` ADD COLUMN `c2` int(11);" ], "synced": [ "mysql-replica-02" ], "unsynced": [ "mysql-replica-01" ] } ] }unlock-ddl-lock
を使用してDM-master
にロックのロックを解除するように依頼します。ロック解除プロセス中に、所有者はダウンストリームに対してDDL操作を再度実行しようとします(再起動する前の元の所有者は、ダウンストリームに対してDDL操作を1回実行しました)。 DDL操作を複数回実行できることを確認してください。
unlock-ddl-lock test-`shard_db`.`shard_table` { "result": true, "msg": "", }
show-ddl-locks
を使用して、DDLロックが正常にロック解除されたかどうかを確認します。query-status
を使用して、移行タスクが正常かどうかを確認します。
影響
ロックを手動でロック解除した後、次のシャーディングDDLを自動的かつ通常どおりに移行できます。