任务管理语句是PolarDB-X专有的扩展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)