任務管理語句是PolarDB-X 1.0專有的擴展SQL語句,可用于查看DDL任務的狀態、恢復或回滾失敗的DDL任務等。本文將詳細介紹任務管理語句的語法和用法。

查看任務

您可以在DDL隊列中查看正在執行(即非PENDING狀態)的任務或失敗待處理(即PENDING狀態)的任務詳情。
說明 已完成(即COMPLETED狀態)的任務會被自動清理,無法通過SHOW DDL語句查看。
  • 語法
    SHOW [FULL] DDL
    參數 說明
    FULL 顯示DDL任務的所有信息,若不帶該參數則結果集中只顯示如下常用信息:
    • JOB_ID
    • OBJECT_SCHEMA
    • OBJECT_NAME
    • JOB_TYPE
    • PHASE
    • STATE
    • PROGRESS
    • START_TIME
    • END_TIME
    • ELAPSED_TIME
    • REMARK
    • PHY_PROCESS
    • BACKFILL_PROGRESS
  • 結果集中各字段的含義
    字段 含義
    JOB_ID DDL任務唯一標識,取值需為64位有符號長整型數值。
    PARENT_JOB_ID 該DDL任務的父任務唯一標識,取值需為64位有符號長整型數值。
    說明 當目標DDL任務為獨立無父任務時,該參數取值為0。
    SERVER 執行DDL任務的DRDS節點信息。
    OBJECT_SCHEMA DDL任務對象的Schema名稱,即當前數據庫名稱。
    OBJECT_NAME DDL任務對象名稱,例如當前執行DDL的表名稱。
    NEW_OBJECT_NAME DDL任務新對象名稱。
    說明 僅當DDL任務類型為RENAME TABLE時顯示該參數,表示目標表的新名稱。
    JOB_TYPE DDL任務類型。
    PHASE DDL任務當前所處的階段。
    STATE DDL任務當前所處的狀態。
    PROGRESS DDL任務執行進度。
    START_TIME DDL任務開始執行的時間。
    END_TIME DDL任務結束執行的時間。
    ELAPSED_TIME DDL任務截止到任務查看時已經消耗的時間,單位為毫秒。
    DDL_STMT 原始的DDL語句。
    REMARK DDL任務的備注信息。
    說明 當DDL任務狀態為PENDING時,該參數會顯示DDL任務失敗的原因。
  • 示例

    創建一個既分庫又分表的拆分表,執行過程中查看狀態。

    1. 在一個連接上執行建表DDL:
      mysql> create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64;
    2. 在另一個連接上查看DDL任務執行狀態:
      mysql> show full ddl\G
      *************************** 1. row ***************************
          JOB_ID: 1103792075578957824
      PARENT_JOB_ID: 0
          SERVER: 1:102:10.81.69.55
      OBJECT_SCHEMA: ddltest
      OBJECT_NAME: test_mdb_mtb
      NEW_OBJECT_NAME:
        JOB_TYPE: CREATE_TABLE
           PHASE: EXECUTE
           STATE: RUNNING
        PROGRESS: 90%
      START_TIME: 2019-08-29 14:29:58.787
        END_TIME: 2019-08-29 14:30:07.177
      ELAPSED_TIME(MS): 8416
        DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64
          REMARK:

恢復任務

恢復失敗待處理(即PENDING狀態)的DDL任務。
說明 恢復任務前,建議您先通過SHOW DDL仔細查看任務中斷或者失敗的原因,找到并解決導致DDL任務失敗的因素后,再執行恢復任務的操作,否則恢復任務可能會遭遇同樣的問題導致失敗。
  • 語法
    RECOVER DDL { ALL | <job_id> [ , <job_id> ] ... }
    參數 說明
    ALL 恢復所有處于PENDING狀態的DDL任務,被恢復的任務會串行執行,請慎用此參數。
    job_id 通過SHOW DDL查看到的處于PENDING狀態的任務ID。
  • 示例

    創建一個既分庫又分表的拆分表,任務執行過程中被中斷,通過SHOW DDL查看狀態和job_id,然后用RECOVER DDL恢復任務,直至該表創建完成。

    1. 建表DDL任務在執行過程中被中斷:
      mysql> create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64;
      ^C^C -- query aborted
    2. 查看DDL任務的信息,被中斷的DDL任務處于PENDING狀態:
      mysql> show ddl\G
      *************************** 1. row ***************************
           JOB_ID: 1103796219480006656
      OBJECT_SCHEMA: ddltest
      OBJECT_NAME: test_mdb_mtb
        JOB_TYPE: CREATE_TABLE
            PHASE: EXECUTE
            STATE: PENDING
        PROGRESS: 33%
      START_TIME: 2019-08-29 14:46:26.769
        END_TIME: 2019-08-29 14:46:29.691
      ELAPSED_TIME(MS): 2922
        DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64
           REMARK: The job has been interrupted unexpectedly
    3. 使用RECOVER DDL恢復該任務:
      mysql> recover ddl 1103796219480006656;
      Query OK, 0 rows affected (7.28 sec)
    4. 通過CHECK TABLE檢查該表的一致性:
      mysql> check table test_mdb_mtb;
      +----------------------------------------+-------+----------+----------+
      | TABLE                                  | OP    | MSG_TYPE | MSG_TEXT |
      +----------------------------------------+-------+----------+----------+
      | ddltest_1562056402230oymk.test_mdb_mtb | check | status   | OK       |
      +----------------------------------------+-------+----------+----------+
      1 row in set (2.24 sec)

回滾任務

回滾失敗待處理(即PENDING狀態)的DDL任務。
說明 目前僅對CREATE TABLE和RENAME TABLE兩種類型的DDL任務支持回滾。對于其它不支持回滾的DDL任務,建議恢復任務后,再執行其它DDL操作。
  • 語法
    ROLLBACK DDL <job_id> [ , <job_id> ] ...
    參數 說明
    job_id 通過SHOW DDL查看到的處于PENDING狀態的任務ID。
  • 示例

    創建一個既分庫又分表的拆分表,任務執行過程中被中斷,通過SHOW DDL查看狀態和job_id,然后用ROLLBACK DDL回滾任務。

    1. 建表DDL任務在執行過程中被中斷:
      mysql> create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64;
      ^C^C -- query aborted
    2. 查看DDL任務的信息,被中斷的DDL任務處于PENDING狀態:
      mysql> show ddl\G
      *************************** 1. row ***************************
           JOB_ID: 1103797850607083520
      OBJECT_SCHEMA: ddltest
      OBJECT_NAME: test_mdb_mtb
        JOB_TYPE: CREATE_TABLE
            PHASE: EXECUTE
            STATE: PENDING
        PROGRESS: 40%
      START_TIME: 2019-08-29 14:52:55.660
        END_TIME: 2019-08-29 14:52:58.885
      ELAPSED_TIME(MS): 3225
        DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64
           REMARK: The job has been interrupted unexpectedly
    3. 使用ROLLBACK DDL回滾該任務:
      mysql> rollback ddl 1103797850607083520;
      Query OK, 0 rows affected (6.42 sec)
    4. 回滾成功,該表不存在:
      mysql> show tables like 'test_mdb_mtb';
      Empty set (0.00 sec)

取消任務

取消正在執行中(即非PENDING狀態)的DDL任務。

  • 語法
    CANCEL DDL <job_id> [ , <job_id> ] ...
    參數 說明
    job_id 通過SHOW DDL查看到的處于非PENDING狀態的任務ID。
  • 示例

    創建一個既分庫又分表的拆分表,任務執行過程中通過CANCEL DDL取消,通過SHOW DDL查看狀態和 job_id,后續可以恢復或者回滾該任務。

    1. 在一個連接上執行建表DDL:
      mysql> create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64;                            
    2. 在另一個連接上通過SHOW DDL查看正在執行中的DDL任務:
      mysql> show ddl\G
      *************************** 1. row ***************************
         JOB_ID: 1103798959568478208
      OBJECT_SCHEMA: ddltest
      OBJECT_NAME: test_mdb_mtb
       JOB_TYPE: CREATE_TABLE
           PHASE: EXECUTE
           STATE: RUNNING
       PROGRESS: 26%
      START_TIME: 2019-08-29 14:57:20.058
       END_TIME: 2019-08-29 14:57:22.284
      ELAPSED_TIME(MS): 2243
       DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64
         REMARK:
    3. 執行CANCEL DDL取消該DDL任務的執行:
      mysql> cancel ddl 1103798959568478208;
      Query OK, 2 rows affected (0.03 sec)
    4. 再通過SHOW DDL查看,DDL任務已被取消執行并處于PENDING狀態:
      mysql> show ddl\G
      *************************** 1. row ***************************
         JOB_ID: 1103798959568478208
      OBJECT_SCHEMA: ddltest
      OBJECT_NAME: test_mdb_mtb
       JOB_TYPE: CREATE_TABLE
           PHASE: EXECUTE
           STATE: PENDING
       PROGRESS: 87%
      START_TIME: 2019-08-29 14:57:20.058
       END_TIME: 2019-08-29 14:57:28.899
      ELAPSED_TIME(MS): 8841
       DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64
         REMARK: ERR-CODE: [TDDL-4636][ERR_DDL_JOB_ERROR] The job '1103798959568478208' has been cancelled.

刪除任務

刪除失敗待處理(即PENDING狀態)的DDL任務,并清理對應的緩存。
警告 請謹慎操作REMOVE DDL刪除任務。執行刪除PENDING任務的操作后,可能會暴露DDL執行過程中的中間狀態,從而影響后續操作。因此,若您不確定PENDING任務是否可以安全刪除時,請不要執行REMOVE DDL語句刪除任務,建議您優先使用恢復或者回滾任務解除PENDING狀態。
  • 語法
    REMOVE DDL { ALL PENDING | <job_id> [ , <job_id> ] ... }
    參數 說明
    ALL PENDING 刪除所有處于PENDING狀態的任務,同時清理內部緩存。
    job_id 通過SHOW DDL查看到的處于PENDING狀態的任務ID。
  • 示例

    數據庫已有兩張表,之間建立了參照完整性關系,當嘗試刪除父表時報錯,因為存在參照完整性約束不允許刪除,如果此時不想再執行刪除表的操作,那么可以刪除該DDL任務。

    1. 數據庫中存在兩張具有參照完整性關系的父子表:
      mysql> show create table test_parent\G
      *************************** 1. row ***************************
      Table: test_parent
      Create Table: CREATE TABLE `test_parent` (
      `id` int(11) NOT NULL,
      `pkey` int(11) NOT NULL,
      `col` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`,`pkey`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by hash(`id`)
      1 row in set (0.01 sec)
      mysql> show create table test_child\G
      *************************** 1. row ***************************
      Table: test_child
      Create Table: CREATE TABLE `test_child` (
      `id` int(11) DEFAULT NULL,
      `parent_id` int(11) DEFAULT NULL,
      KEY `parent_id` (`parent_id`),
      CONSTRAINT `test_child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `test_parent` (`id`) ON DELETE CASCADE
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by hash(`parent_id`)
      1 row in set (0.02 sec)
    2. 因為存在參照完整性約束,嘗試刪除父表報錯:
      mysql> drop table test_parent;
      ERROR 4636 (HY000): [f518265d0066000][10.81.69.55:3306][ddltest]ERR-CODE: [TDDL-4636][ERR_DDL_JOB_ERROR] Not all physical operations have been done successfully: expected 9,
      but done 0. Caused by: 1217:DDLTEST_1562056402230OYMK_7WW7_0007:Cannot delete or update a parent row: a foreign key constraint fails on `test_parent`;1217:DDLTEST_15620564022
      30OYMK_7WW7_0000:Cannot delete or update a parent row: a foreign key constraint fails on `test_parent`;1217:DDLTEST_1562056402230OYMK_7WW7_0002:Cannot delete or update a pare
      nt row: a
    3. 查看DDL任務:
      mysql> show ddl\G
      *************************** 1. row ***************************
           JOB_ID: 1103806757547171840
      OBJECT_SCHEMA: ddltest
      OBJECT_NAME: test_parent
        JOB_TYPE: DROP_TABLE
            PHASE: EXECUTE
            STATE: PENDING
        PROGRESS: 0%
      START_TIME: 2019-08-29 15:28:19.240
        END_TIME: 2019-08-29 15:28:19.456
      ELAPSED_TIME(MS): 216
        DDL_STMT: drop table test_parent
           REMARK: ERR-CODE: [TDDL-4636][ERR_DDL_JOB_ERROR] Not all physical operations have been done successfully: expected 9, but done 0. Caused by: 1217:DDLTEST_1562056402
      230OYMK_7WW7_0007:Cannot delete or update a parent row: a foreign key constraint fails on `test_pare ...
    4. 該DDL任務執行刪除表的操作時,違反了參照完整性約束,因此刪除操作并未真正執行,此時CHECK TABLE該表仍然是一致的:
      mysql> check table test_parent;
      +---------------------------------------+-------+----------+----------+
      | TABLE                                 | OP    | MSG_TYPE | MSG_TEXT |
      +---------------------------------------+-------+----------+----------+
      | ddltest_1562056402230oymk.test_parent | check | status   | OK       |
      +---------------------------------------+-------+----------+----------+
      1 row in set (0.05 sec)
    5. 但由于該表上有PENDING狀態的任務存在,因此此時表處于不可訪問狀態:
      mysql> show tables like 'test_parent';
      Empty set (0.00 sec)
      mysql> show create table test_parent;
      ERROR 4642 (HY000): [f5185a78b066000][10.81.69.55:3306][ddltest]ERR-CODE: [TDDL-4642][ERR_UNKNOWN_TABLE] Unknown table 'ddltest.test_parent'                            
    6. 此時該刪除表的任務并沒有真正開始執行,表結構仍然一致,雖然看似可以選擇回滾失敗的DDL操作,但由于DROP TABLE并不允許回滾,回滾操作并不可行,因此必須選擇刪除該失敗的DDL任務:
      mysql> remove ddl 1103806757547171840;
      Query OK, 1 row affected (0.02 sec)
    7. 刪除該DDL任務后,表恢復正常訪問的狀態:
      mysql> show tables like 'test_parent';
      +-------------------+
      | TABLES_IN_DDLTEST |
      +-------------------+
      | test_parent       |
      +-------------------+
      1 row in set (0.01 sec)