天天看點

跳過或替代執行異常的 SQL 語句

本文介紹了如何使用 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

tbl1

(

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

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

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。