本文介紹了如何使用 DM 來處理異常的 SQL 語句。
目前,TiDB 并不完全相容所有的 MySQL 文法(詳見 TiDB 已支援的 DDL 語句)。當使用 DM 從 MySQL 同步資料到 TiDB 時,如果 TiDB 不支援對應的 SQL 語句,可能會造成錯誤并中斷同步任務。在這種情況下,DM 提供以下兩種方式來恢複同步:
使用 dmctl 來手動跳過 (skip) 該 SQL 語句對應的 binlog event。
使用 dmctl 來手動指定其他 SQL 語句來替代 (replace) 該 SQL 語句對應的 binlog event,并向下遊執行。
如果提前預知将要同步 TiDB 不支援的 SQL 語句,也可以使用 dmctl 來手動預設跳過/替代執行操作。當 DM 嘗試将該 SQL 語句對應的 binlog event 同步到下遊時,該預設的操作将自動執行,進而避免同步過程被中斷。
使用限制
跳過/替代執行操作隻适合用于一次性跳過/替代執行下遊 TiDB 不支援執行的 SQL 語句,其它同步錯誤請不要使用此方式進行處理。
其它同步錯誤可嘗試使用 binlog event filter。
如果業務不能接受下遊 TiDB 跳過異常的 DDL 語句,也不接受使用其他 DDL 語句作為替代,則不适合使用此方式進行處理。
比如:DROP PRIMARY KEY
這種情況下,隻能在下遊重建一個(DDL 執行完後的)新表結構對應的表,并将原表的全部資料重新導入該新表。
單次跳過/替代執行操作都是針對單個 binlog event 的。
--sharding 僅用于對 sharding group 預設一些操作,并且必須在 DDL 語句執行之前預設,不能在 DDL 語句已經執行後預設。
--sharding 模式下隻支援預設,并隻能使用 --sql-pattern 來比對 binlog event。
有關使用 DM 處理 sharding DDL 同步的原理,請參閱比對 binlog event
當同步任務由于執行 SQL 語句出錯而中斷時,可以使用 query-error 指令擷取對應 binlog event 的 position 資訊。在執行 sql-skip / sql-replace 時,通過指定該 position 資訊,即可與對應的 binlog event 進行比對。
然而,在同步中斷前主動處理不被支援的 SQL 語句的情況下,由于無法提前預知 binlog event 的 position 資訊,則需要使用其他方式來確定與後續将到達的 binlog event 進行比對。
在 DM 中,支援如下兩種 binlog event 比對模式(兩種模式隻能選擇其中一種):
binlog position:binlog event 的 position 資訊
binlog position 在指令中使用 --binlog-pos 參數傳入,格式為 binlog-filename:binlog-pos,如 mysql-bin|000001.000003:3270。
DM 中 binlog filename 的格式與上遊 MySQL 中 binlog filename 的格式不完全一緻。
在同步執行出錯後,binlog position 可直接從 query-error 傳回的 failedBinlogPosition 中獲得。
DDL pattern:(僅限于 DDL 語句的)正規表達式比對模式
DDL pattern 在指令中使用 --sql-pattern 參數傳入,如要比對 ALTER TABLE
db2
. tbl2
DROP COLUMN c2
,則對應的正規表達式為 ~(?i)ALTER\s+TABLE\s+ db2
tbl2
\s+DROP\s+COLUMN\s+ c2
。
正規表達式必須以 ~ 為字首,且不包含任何原始空格(正規表達式字元串中的空格均以 \s 或 \s+ 表示)。
對于合庫合表場景,如果需要由 DM 自動選擇 DDL lock owner 來執行跳過/替代執行操作,則由于不同 DM-worker 上 DDL 語句對應的 binlog position 無邏輯關聯且難以确定,是以隻能使用 DDL pattern 比對模式。
注意:
一個 binlog event 隻能注冊一個使用 --binlog-pos 指定的 operator,後注冊的 operator 會覆寫之前已經注冊的 operator。
不要嘗試為一個 binlog event 同時使用 --binlog-pos 和 --sql-pattern 指定 operator。
operator 在與 binlog event 比對成功後(而非執行成功後)即會被删除,後續如果需要再進行(--sql-pattern)比對則必須重新注冊。
支援場景
場景一:同步過程中,上遊執行了 TiDB 不支援的 DDL 語句并同步到了 DM,造成同步任務中斷。
如果業務能接受下遊 TiDB 不執行該 DDL 語句,則使用 sql-skip 跳過對該 DDL 語句的同步以恢複同步任務。
如果業務能接受下遊 TiDB 執行其他 DDL 語句來作為替代,則使用 sql-replace 替代該 DDL 的同步以恢複同步任務。
場景二:同步過程中,預先知道了上遊将執行 TiDB 不支援的 DDL 語句,則需要提前處理以避免同步任務中斷。
如果業務能接受下遊 TiDB 不執行該 DDL 語句,則使用 sql-skip 預設一個跳過該 DDL 語句的操作,當執行到該 DDL 語句時即自動跳過。
如果業務能接受下遊 TiDB 執行其他 DDL 語句來作為替代,則使用 sql-replace 預設一個替代該 DDL 語句的操作,當執行到該 DDL 語句時即自動替代。
實作原理
DM 在進行增量資料同步時,簡化後的流程大緻為:
relay 處理單元從上遊拉取 binlog 存儲在本地作為 relay log。
binlog 同步單元(sync)讀取本地 relay log,擷取其中的 binlog event。
binlog 同步單元解析該 binlog event 并構造 DDL/DML 語句,然後将這些語句向下遊 TiDB 執行。
在 binlog 同步單元解析完 binlog event 并向下遊 TiDB 執行時,可能會由于 TiDB 不支援對應的 SQL 語句而報錯并造成同步中斷。
在 DM 中,可以為 binlog event 注冊一些跳過/替代執行操作(operator)。在向下遊 TiDB 執行 SQL 語句前,将目前的 binlog event 資訊(position、DDL 語句)與注冊的 operator 進行比較。如果 position 或 DDL 語句與注冊的某個 operator 比對,則執行該 operator 對應的操作并将該 operator 移除。
同步中斷後使用 sql-skip 或 sql-replace 恢複同步的流程
使用 sql-skip 或 sql-replace 為指定的 binlog position 或 DDL pattern 注冊 operator。
使用 resume-task 恢複之前由于同步出錯導緻中斷的任務。
重新解析獲得之前造成同步出錯的 binlog event。
該 binlog event 與第一步注冊的 operator 比對成功。
執行 operator 對應的操作(跳過/替代執行)後,繼續執行同步任務。
同步中斷前使用 sql-skip 或 sql-replace 預設操作以避免同步中斷的流程
使用 sql-skip 或 sql-replace 為指定的 DDL pattern 注冊 operator。
從 relay log 中解析獲得 binlog event。
(包含 TiDB 不支援 SQL 語句的)binlog event 與第一步注冊的 operator 比對成功。
執行 operator 對應的操作(跳過/替代執行)後,繼續執行同步任務,任務不發生中斷。
合庫合表同步中斷前使用 sql-skip 或 sql-replace 預設操作以避免同步中斷的流程
使用 sql-skip 或 sql-replace(在 DM-master 上)為指定的 DDL pattern 注冊 operator。
各 DM-worker 從 relay log 中解析獲得 binlog event。
DM-master 協調各個 DM-worker 進行 DDL lock 同步。
DM-master 判斷得知 DDL lock 同步成功後,将第一步注冊的 operator 發送給 DDL lock owner。
DM-master 請求 DDL lock owner 執行 DDL 語句。
DDL lock owner 将要執行的 DDL 語句與第四步收到的 operator 比對成功。
指令介紹
使用 dmctl 手動處理 TiDB 不支援的 SQL 語句時,主要使用的指令包括 query-status、query-error、sql-skip 和 sql-replace。
query-status
query-status 指令用于查詢目前 DM-worker 内子任務及 relay 單元等的狀态,詳見query-error
query-error 指令用于查詢 DM-worker 内子任務及 relay 單元目前在運作中存在的錯誤。
指令用法
query-error [--worker=127.0.0.1:8262] [task-name]
參數解釋
worker:
flag 參數,string,--worker,可選;
不指定時查詢所有 DM-worker 上的錯誤,指定時僅查詢特定一組 DM-worker 上的錯誤。
task-name:
非 flag 參數,string,可選;
不指定時查詢所有任務内的錯誤,指定時僅查詢特定任務内的錯誤。
結果示例
» query-error test
{
"result": true, # query-error 操作本身是否成功
"msg": "", # query-error 操作失敗的說明資訊
"workers": [ # DM-worker 資訊清單
{
"result": true, # 該 DM-worker 上 query-error 操作是否成功
"worker": "127.0.0.1:8262", # 該 DM-worker 的 IP:port(worker-id)
"msg": "", # 該 DM-worker 上 query-error 操作失敗的說明資訊
"subTaskError": [ # 該 DM-worker 上運作子任務的錯誤資訊
{
"name": "test", # 任務名
"stage": "Paused", # 目前任務的狀态
"unit": "Sync", # 目前正在處理任務的處理單元
"sync": { # binlog 同步單元(sync)的錯誤資訊
"errors": [ # 目前處理單元的錯誤資訊清單
{
// 錯誤資訊描述
"msg": "exec sqls[[USE `db1`; ALTER TABLE `db1`.`tbl1` CHANGE COLUMN `c2` `c2` decimal(10,3);]] failed, err:Error 1105: unsupported modify column length 10 is less than origin 11",
// 發生錯誤的 binlog event 的 position
"failedBinlogPosition": "mysql-bin|000001.000003:34642",
// 發生錯誤的 SQL 語句
"errorSQL": "[USE `db1`; ALTER TABLE `db1`.`tbl1` CHANGE COLUMN `c2` `c2` decimal(10,3);]"
}
]
}
}
],
"RelayError": { # 該 DM-worker 上 relay 處理單元的錯誤資訊
"msg": "" # 錯誤資訊描述
}
}
]
}
sql-skip
sql-skip 指令用于預設一個跳過操作,當 binlog event 的 position 或 SQL 語句與指定的 binlog-pos 或 sql-pattern 比對時,執行該跳過操作。
sql-skip <--worker=127.0.0.1:8262> [--binlog-pos=mysql-bin|000001.000003:3270] [--sql-pattern=~(?i)ALTER\s+TABLE\s+
db1
tbl1
\s+ADD\s+COLUMN\s+col1\s+INT] [--sharding]
flag 參數,string,--worker;
未指定 --sharding 時必選,指定 --sharding 時禁止使用;
worker 指定預設操作将生效的 DM-worker。
binlog-pos:
flag 參數,string,--binlog-pos;
binlog-pos 與 --sql-pattern 必須指定其中一個,且隻能指定其中一個。
在指定時表示操作将在 binlog-pos 與 binlog event 的 position 比對時生效,格式為 binlog-filename:binlog-pos,如 mysql-bin|000001.000003:3270。
sql-pattern:
flag 參數,string,--sql-pattern;
--sql-pattern 與 binlog-pos 必須指定其中一個,且隻能指定其中一個。
在指定時表示操作将在 sql-pattern 與 binlog event 對應的(經過可選的 router-rule 轉換後的)DDL 語句比對時生效。格式為以 ~ 為字首的正規表達式,如 ~(?i)ALTER\s+TABLE\s+
db1
tbl1
\s+ADD\s+COLUMN\s+col1\s+INT。
暫時不支援正規表達式中包含原始空格,需要使用 \s 或 \s+ 替代空格。
正規表達式必須以 ~ 為字首,詳見正規表達式文法。
正規表達式中的庫名和表名必須是經過可選的 router-rule 轉換後的名字,
賣QQ賬号即對應下遊的目标庫名和表名。如上遊為
shard_db_1
shard_tbl_1
,下遊為
shard_db
shard_tbl
,則應該嘗試比對
shard_db
shard_tbl
正規表達式中的庫名、表名及列名需要使用
标記,如
db1
.
tbl1`。
sharding:
flag 參數,boolean,--sharding;
未指定 --worker 時必選,指定 --worker 時禁止使用;
在指定時表示預設的操作将在 sharding DDL 同步過程中的 DDL lock owner 内生效。
非 flag 參數,string,必選;
指定預設的操作将生效的任務。
sql-replace
sql-replace 指令用于預設一個替代執行操作,當 binlog event 的 position 或 SQL 語句與指定的 binlog-pos 或 sql-pattern 比對時,執行該替代執行操作。
sql-replace <--worker=127.0.0.1:8262> [--binlog-pos=mysql-bin|000001.000003:3270] [--sql-pattern=~(?i)ALTER\s+TABLE\s+
db1
tbl1
\s+ADD\s+COLUMN\s+col1\s+INT] [--sharding] <SQL-1;SQL-2>
與 sql-skip 指令的 --worker 參數解釋一緻。
與 sql-skip 指令的 --binlog-pos 參數解釋一緻。
與 sql-skip 指令的 --sql-pattern 參數解釋一緻。
與 sql-skip 指令的 --sharding 參數解釋一緻。
與 sql-skip 指令的 task-name 參數解釋一緻。
SQLs:
SQLs 指定将用于替代原 binlog event 的新的 SQL 語句。多條 SQL 語句間以 ; 分隔,如 ALTER TABLE shard_db.shard_table drop index idx_c2;ALTER TABLE shard_db.shard_table DROP COLUMN c2;。
使用示例
同步中斷後被動執行跳過操作
應用場景
假設現在需要将上遊的 db1.tbl1 表同步到下遊 TiDB(非合庫合表同步場景),初始時表結構為:
SHOW CREATE TABLE db1.tbl1; | |
---|---|
Table | Create Table |
tbl1 | CREATE TABLE ( |
c1
int(11) NOT NULL,
c2
decimal(11,3) DEFAULT NULL,
PRIMARY KEY (
c1
)
此時,上遊執行以下 DDL 操作修改表結構(将列的 DECIMAL(11, 3) 修改為 DECIMAL(10, 3)):
ALTER TABLE db1.tbl1 CHANGE c2 c2 DECIMAL (10, 3);
則會由于 TiDB 不支援該 DDL 語句而導緻 DM 同步任務中斷且報如下錯誤:
exec sqls[[USE
db1
; ALTER TABLE
db1
tbl1
CHANGE COLUMN
c2
c2
decimal(10,3);]] failed,
err:Error 1105: unsupported modify column length 10 is less than origin 11
此時使用 query-status 查詢任務狀态,可看到 stage 轉為了 Paused,且 errors 中有相關的錯誤描述資訊。
使用 query-error 可以擷取該錯誤的詳細資訊。比如,執行 query-error test 可獲得出錯的 binlog event 的 position(failedBinlogPosition)為 mysql-bin|000001.000003:34642。
被動跳過 SQL 語句
假設業務上可以接受下遊 TiDB 不執行此 DDL 語句(即繼續保持原有的表結構),則可以通過使用 sql-skip 指令跳過該 DDL 語句以恢複同步任務。操作步驟如下:
使用 query-error 擷取同步出錯的 binlog event 的 position 資訊。
position 資訊可直接由 query-error 傳回的 failedBinlogPosition 獲得。
本示例中的 position 為 mysql-bin|000001.000003:34642。
使用 sql-skip 預設一個 binlog event 跳過操作,該操作将在使用 resume-task 後同步該 binlog event 到下遊時生效。
» sql-skip --worker=127.0.0.1:8262 --binlog-pos=mysql-bin|000001.000003:34642 test
"result": true,
"msg": "",
"workers": [
{
"result": true,
"worker": "",
"msg": ""
}
]
對應 DM-worker 節點中也可以看到類似如下日志:
2018/12/28 11:17:51 operator.go:121: [info] [sql-operator] set a new operator
uuid: 6bfcf30f-2841-4d70-9a34-28d7082bdbd7, pos: (mysql-bin|000001.000003, 34642), op: SKIP, args:
on replication unit
使用 resume-task 恢複之前出錯中斷的同步任務。
» resume-task --worker=127.0.0.1:8262 test
"op": "Resume",
"result": true,
"msg": "",
"workers": [
{
"op": "Resume",
"result": true,
"worker": "127.0.0.1:8262",
"msg": ""
}
]
2018/12/28 11:27:46 operator.go:158: [info] [sql-operator] binlog-pos (mysql-bin|000001.000003, 34642) matched,
applying operator uuid: 6bfcf30f-2841-4d70-9a34-28d7082bdbd7, pos: (mysql-bin|000001.000003, 34642), op: SKIP, args:
使用 query-status 确認該任務的 stage 已經轉為 Running。
使用 query-error 确認原錯誤資訊已不再存在。
同步中斷前主動執行替代執行操作
假設現在需要将上遊的 db2.tbl2 表同步到下遊 TiDB(非合庫合表同步場景),初始時表結構為:
SHOW CREATE TABLE db2.tbl2; | |
---|---|
tbl2 | |
c1
c2
int(11) DEFAULT NULL,
c1
),
KEY
idx_c2
c2
此時,上遊執行以下 DDL 操作修改表結構(即 DROP 列 c2):
ALTER TABLE db2.tbl2 DROP COLUMN c2;
當同步該 DDL 語句對應的 binlog event 到下遊時,會由于 TiDB 不支援該 DDL 語句而導緻 DM 同步任務中斷且報如下錯誤:
db2
db2
tbl2
c2
;]] failed,
err:Error 1105: can't drop column c2 with index covered now
但如果在上遊實際執行該 DDL 語句前,你已提前知道該 DDL 語句不被 TiDB 所支援。則可以使用 sql-skip 或 sql-replace 為該 DDL 語句預設一個跳過(skip)或替代執行(replace)操作。
對于本示例中的 DDL 語句,由于 TiDB 暫時不支援 DROP 存在索引的列,是以可以使用兩條新的 SQL 語句來進行替代執行操作,即可以先 DROP 索引、然後再 DROP 列 c2。
主動替代執行該 SQL 語句
為将要在上遊執行的 DDL 語句(經過可選的 router-rule 轉換後的 DDL 語句)設計一個能比對上的正規表達式。
上遊将執行的 DDL 語句為 ALTER TABLE db2.tbl2 DROP COLUMN c2;。
由于該 DDL 語句不存在 router-rule 轉換,可設計如下正規表達式:
~(?i)ALTER\s+TABLE\s+
db2
tbl2
c2
為該 DDL 語句設計将用于替代執行的新的 DDL 語句:
ALTER TABLE
db2
tbl2
DROP INDEX idx_c2;ALTER TABLE
db2
tbl2
c2
;
使用 sql-replace 預設一個 binlog event 替代執行操作,該操作将在同步該 binlog event 到下遊時生效。
» sql-replace --worker=127.0.0.1:8262 --sql-pattern=~(?i)ALTER\s+TABLE\s+
db2
tbl2
c2
test ALTER TABLE
db2
tbl2
db2
tbl2
c2
"result": true,
"msg": "",
"workers": [
{
"result": true,
"worker": "",
"msg": ""
}
]
2018/12/28 15:33:13 operator.go:121: [info] [sql-operator] set a new operator
uuid: c699a18a-8e75-47eb-8e7e-0e5abde2053c, pattern: ~(?i)ALTER\s+TABLE\s+
db2
tbl2
c2
,
op: REPLACE, args: ALTER TABLE
db2
tbl2
DROP INDEX idx_c2; ALTER TABLE
db2
tbl2
c2
在上遊 MySQL 執行該 DDL 語句。
觀察下遊表結構是否變更成功,對應 DM-worker 節點中也可以看到類似如下日志:
2018/12/28 15:33:45 operator.go:158: [info] [sql-operator]
sql-pattern ~(?i)ALTER\s+TABLE\s+
db2
tbl2
c2
matched SQL
USE
db2
db2
tbl2
c2
;,
applying operator uuid: c699a18a-8e75-47eb-8e7e-0e5abde2053c,
pattern: ~(?i)ALTER\s+TABLE\s+
db2
tbl2
c2
db2
tbl2
db2
tbl2
c2
使用 query-status 确認該任務的 stage 持續為 Running。
使用 query-error 确認不存在 DDL 執行錯誤。
合庫合表場景下同步中斷後被動執行跳過操作
假設現在通過多個 DM-worker 将上遊多個 MySQL 執行個體内的多個表進行合庫合表同步到下遊 TiDB 的同一個表,并且上遊各分表執行了 TiDB 不支援的 DDL 語句。
DM-master 通過 DDL lock 協調 DDL 同步、并請求 DDL lock owner 向下遊 TiDB 執行該 DDL 語句後,由于 TiDB 不支援該 DDL 語句,同步任務會報錯并中斷。
合庫合表場景下,被動跳過 TiDB 不支援的 DDL 語句的處理方式與非合庫合表場景下的但在合庫合表場景下,隻需要 DDL lock owner 向下遊同步該 DDL 語句,是以在兩種場景下的處理過程主要存在以下差別:
合庫合表場景下,僅需要對 DDL lock owner 執行 sql-skip(--worker={DDL-lock-owner})。
合庫合表場景下,僅需要對 DDL lock owner 執行 resume-task(--worker={DDL-lock-owner})。
合庫合表場景下同步中斷前主動執行替代執行操作
假設現在存在如下四個上遊表需要合并同步到下遊的同一個表
shard_db
shard_table
:
MySQL 執行個體 1 内有 shard_db_1 邏輯庫,包括 shard_table_1 和 shard_table_2 兩個表。
MySQL 執行個體 2 内有 shard_db_2 邏輯庫,包括 shard_table_1 和 shard_table_2 兩個表。
初始時表結構為:
SHOW CREATE TABLE shard_db_1.shard_table_1; | |
---|---|
shard_table_1 | |
c1
c2
c1
idx_c2
c2
此時,在上遊所有分表上都執行以下 DDL 操作修改表結構(即 DROP 列 c2):
ALTER TABLE shard_db_.shard_table_ DROP COLUMN c2;
則當 DM 通過 sharding DDL lock 協調兩個 DM-worker 同步該 DDL 語句、并請求 DDL lock owner 向下遊執行該 DDL 語句時,會由于 TiDB 不支援該 DDL 語句而導緻同步任務中斷且報如下錯誤:
shard_db
shard_db
shard_table
c2
但如果在上遊實際執行該 DDL 語句前,你已提前知道該 DDL 語句不被 TiDB 所支援。則可以使用 sql-skip 或 sql-replace 指令為該 DDL 語句預設一個跳過/替代執行操作。
對于本示例中的 DDL 語句,由于 TiDB 暫時不支援 DROP 存在索引的列,是以可以使用兩條新的 SQL 語句來進行替代執行操作,即可以先 DROP 索引、然後再 DROP c2 列。
為将要在上遊執行的(經過可選的 router-rule 轉換後的)DDL 語句設計一個能比對上的正規表達式。
上遊将執行的 DDL 語句為 ALTER TABLE shard_db_.shard_table_ DROP COLUMN c2。
由于存在 router-rule 會将表名轉換為
shard_db
shard_table
,可設計如下正規表達式:
shard_db
shard_table
c2
shard_db
shard_table
shard_db
shard_table
c2
由于這是合庫合表場景,是以使用 --sharding 參數來由 DM 自動确定替代執行操作隻發生在 DDL lock owner 上。
» sql-replace --sharding --sql-pattern=~(?i)ALTER\s+TABLE\s+
shard_db
shard_table
c2
shard_db
shard_table
shard_db
shard_table
c2
"result": true,
"msg": "request with --sharding saved and will be sent to DDL lock's owner when resolving DDL lock",
"workers": [
]
DM-master 節點中也可以看到類似如下日志:
2018/12/28 16:53:33 operator.go:105: [info] [sql-operator] set a new operator
uuid: eba35acd-6c5e-4bc3-b0b0-ae8bd1232351, request: name:"test"
op:REPLACE args:"ALTER TABLE
shard_db
shard_table
DROP INDEX idx_c2;"
args:"ALTER TABLE
shard_db
shard_table
c2
"
sqlPattern:"~(?i)ALTER\s+TABLE\s+
shard_db
shard_table
c2
sharding:true
在上遊 MySQL 執行個體的分表上執行 DDL 語句。
觀察下遊表結構是否變更成功,對應的 DDL lock owner 節點中也可以看到類似如下日志:
2018/12/28 16:54:35 operator.go:121: [info] [sql-operator] set a new operator
uuid: c959f2fb-f1c2-40c7-a1fa-e73cd51736dd,
shard_db
shard_table
c2
shard_db
shard_table
shard_db
shard_table
c2
2018/12/28 16:54:35 operator.go:158: [info] [sql-operator]
shard_db
shard_table
c2
shard_db
shard_db
shard_table
c2
applying operator uuid: c959f2fb-f1c2-40c7-a1fa-e73cd51736dd,
shard_db
shard_table
c2
shard_db
shard_table
shard_db
shard_table
c2
另外,DM-master 節點中也可以看到類似如下日志:
2018/12/28 16:54:35 operator.go:122: [info] [sql-operator] get an operator
uuid: eba35acd-6c5e-4bc3-b0b0-ae8bd1232351, request: name:"test" op:REPLACE
shard_db
shard_table
shard_db
shard_table
c2
shard_db
shard_table
c2
with key ~(?i)ALTER\s+TABLE\s+
shard_db
shard_table
c2
shard_db
shard_db
shard_table
c2
2018/12/28 16:54:36 operator.go:145: [info] [sql-operator] remove an operator
shard_db
shard_table
shard_db
shard_table
c2
shard_db
shard_table
c2
使用 query-status 确認任務的 stage 持續為 Running,且不存在正阻塞同步的 DDL 語句(blockingDDLs)與待解決的 sharding group(unresolvedGroups)。
使用 show-ddl-locks 确認不存在待解決的 DDL lock。