DDL任务管理语句
任务管理语句是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任务失败的原因。 - 示例
创建一个既分库又分表的拆分表,执行过程中查看状态。
- 在一个连接上执行建表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;
- 在另一个连接上查看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:
- 在一个连接上执行建表DDL:
恢复任务
恢复失败待处理(即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恢复任务,直至该表创建完成。- 建表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
- 查看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
- 使用RECOVER DDL恢复该任务:
mysql> recover ddl 1103796219480006656; Query OK, 0 rows affected (7.28 sec)
- 通过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)
- 建表DDL任务在执行过程中被中断:
回滚任务
回滚失败待处理(即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回滚任务。- 建表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
- 查看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
- 使用ROLLBACK DDL回滚该任务:
mysql> rollback ddl 1103797850607083520; Query OK, 0 rows affected (6.42 sec)
- 回滚成功,该表不存在:
mysql> show tables like 'test_mdb_mtb'; Empty set (0.00 sec)
- 建表DDL任务在执行过程中被中断:
取消任务
取消正在执行中(即非PENDING状态)的DDL任务。
- 语法
CANCEL DDL <job_id> [ , <job_id> ] ...
参数 说明 job_id 通过SHOW DDL查看到的处于非PENDING状态的任务ID。 - 示例
创建一个既分库又分表的拆分表,任务执行过程中通过CANCEL DDL取消,通过SHOW DDL查看状态和
job_id
,后续可以恢复或者回滚该任务。- 在一个连接上执行建表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;
- 在另一个连接上通过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:
- 执行CANCEL DDL取消该DDL任务的执行:
mysql> cancel ddl 1103798959568478208; Query OK, 2 rows affected (0.03 sec)
- 再通过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.
- 在一个连接上执行建表DDL:
删除任务
删除失败待处理(即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任务。
- 数据库中存在两张具有参照完整性关系的父子表:
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)
- 因为存在参照完整性约束,尝试删除父表报错:
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
- 查看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 ...
- 该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)
- 但由于该表上有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'
- 此时该删除表的任务并没有真正开始执行,表结构仍然一致,虽然看似可以选择回滚失败的DDL操作,但由于DROP TABLE并不允许回滚,回滚操作并不可行,因此必须选择删除该失败的DDL任务:
mysql> remove ddl 1103806757547171840; Query OK, 1 row affected (0.02 sec)
- 删除该DDL任务后,表恢复正常访问的状态:
mysql> show tables like 'test_parent'; +-------------------+ | TABLES_IN_DDLTEST | +-------------------+ | test_parent | +-------------------+ 1 row in set (0.01 sec)
- 数据库中存在两张具有参照完整性关系的父子表: