在MySQL生态中,DDL操作复杂且耗时,稍有不慎,就会影响正常业务。PolarDB MySQL版新增EXPLAIN DDL功能。您可以在执行DDL前了解执行细节,从而正确评估DDL操作对当前业务的影响。
功能介绍
在MySQL生态中,DDL操作非常复杂,不仅耗时长、消耗硬件资源,而且涉及锁表操作,若操作不当可能会影响正常业务,甚至造成灾难性后果。此外,不同的DDL操作具有不同的执行特点,例如,添加字段不需要重建表,通常可以在秒级内完成,而修改字段类型则需要全表重建,并且在执行期间无法进行写操作。
为了帮助您深入了解和评估执行DDL所需的各方面信息,例如当前是否存在锁冲突、DDL操作是否需要重建表等,PolarDB MySQL版新增提供了EXPLAIN DDL功能。与EXPLAIN SQL类似,您可以在执行DDL前对DDL语句进行EXPLAIN,从而获取DDL操作的执行细节。
版本说明
PolarDB MySQL版数据库引擎版本支持如下:
- PolarDB MySQL版8.0.1版本且修订版本为8.0.1.1.49及以上。 
- PolarDB MySQL版8.0.2版本且修订版本为8.0.2.2.27及以上。 
注意事项
- EXPLAIN DDL操作仅支持使用InnoDB存储引擎的表。 
- EXPLAIN DDL操作不会发生任何实际数据变动,您可以放心执行。 
- 主节点和只读节点均可执行EXPLAIN DDL操作,但是Possible blocked MDLs字段仅展示当前节点存在的潜在锁冲突。 
使用说明
参数说明
您可以先通过loose_polar_enable_explain_ddl参数开启EXPLAIN DDL功能,并通过loose_polar_max_collect_thd_num_in_explain_ddl参数设置收集的潜在MDL阻塞线程的数量。具体操作请参见设置集群参数和节点参数。参数说明如下:
| 参数名 | 级别 | 说明 | 
| loose_polar_enable_explain_ddl | Global | EXPLAN DDL功能开关。取值范围如下: 
 | 
| loose_polar_max_collect_thd_num_in_explain_ddl | Global | 控制收集的潜在MDL阻塞线程的数目。 取值范围:[1-512],默认值为16。 | 
语法说明
{ EXPLAIN | DESCRIBE | DESC } 	ALTER TABLE ...输出结果中,各个字段的含义如下:
| 字段 | 含义 | 取值范围 | 
| Error No | 错误码。 | 
 | 
| Algorithm | DDL操作将使用的执行算法。 | 
 | 
| Metadata Only | DDL操作是否仅需修改元信息,无需修改表中数据。 | 
 | 
| Rebuilt table | DDL操作是否需要表重建。 | 
 | 
| Parallel Support | DDL操作是否支持使用并行DDL进行加速。 | 
 | 
| Parallel Degree | DDL操作将使用的线程数。 | 
 | 
| Concurrent DML | 在DDL操作期间是否支持并发读写。 | 
 | 
| Possible blocked MDLs | 可能阻塞DDL操作的其他事务。此处记录事务所在连接的Process ID。 | 由Process ID拼接的字符串。各个ID之间以逗号(,)分隔。 | 
| Error Msg | 与Error No对应,表示当前DDL操作的错误信息。 | 字符串。 | 
| Suggest Info | 当前DDL操作的建议信息。 | 字符串。 说明  包括但不限于如下内容: 
 | 
| Statement | 当前语句。 | DDL语句。 | 
示例
查询DDL操作的执行特征
通过分析EXPLAIN DDL返回结果中的Algorithm、Metadata Only、Rebuilt Table和Concurrent DML字段,您可以方便地了解当前DDL操作的执行特征。
- 当 - Concurrent DML字段为Yes时,表示当前DDL执行期间支持并发的读写操作,不会阻塞业务的读写请求。
- 当 - Rebuilt Table字段为Yes时,表示当前DDL操作需要对整表进行重建。当表空间较大时,通常需要较长时间,因此建议选择业务低峰期执行此类DDL。
- 当 - Metadata Only字段为Yes时,表示当前DDL操作无需修改表中的数据。此类操作可以无视表大小,通常能在秒级完成,对数据库负载影响不大。
以下是一些DDL操作的执行示例:
- 测试表结构如下: - SHOW CREATE TABLE t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` char(1) DEFAULT NULL, `c` char(1) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec)
- 对添加字段操作进行EXPLAIN: - EXPLAIN ALTER TABLE t1 ADD COLUMN d INT;- 执行结果如下: - *************************** 1. row *************************** Error No: 0 Algorithm: INSTANT Metadata Only: Yes Rebuilt table: No Parallel Support: Not Need Parallel Degree: 1 Concurrent DML: Yes Possible blocked MDLs: Error Msg: Suggest Info: Statement: EXPLAIN ALTER TABLE t1 ADD COLUMN d int 1 row in set (0.00 sec)- 结果显示,Algorithm字段值为INSTANT,表示加列操作支持INSTANT算法;Metadata Only字段值为Yes,表示加列操作仅修改元数据,无需表重建;Concurrent DML字段值为Yes,表示加列操作支持并发的DML访问。此类DDL可以秒级内完成,对业务影响较小。 
- 对修改表名操作进行EXPLAIN: - EXPLAIN ALTER TABLE t1 rename t1_rn;- 执行结果如下: - *************************** 1. row *************************** Error No: 0 Algorithm: INPLACE Metadata Only: Yes Rebuilt table: No Parallel Support: Not Need Parallel Degree: 1 Concurrent DML: Yes Possible blocked MDLs: Error Msg: Suggest Info: Statement: EXPLAIN ALTER TABLE t1 rename t1_rn 1 row in set (0.01 sec)- 结果显示,Algorithm字段值为INPLACE,表示修改表名操作支持INPLACE算法;Metadata Only字段值为Yes,表示修改表名操作仅修改元数据,无需表重建; Concurrent DML字段值为Yes,表示修改表名操作支持并发的DML访问。此类DDL操作无需修改表中数据,对业务影响较小。 
- 对修改列定义操作进行EXPLAIN: - EXPLAIN ALTER TABLE t1 modify COLUMN a char(1);- 执行结果如下: - *************************** 1. row *************************** Error No: 0 Algorithm: COPY Metadata Only: No Rebuilt table: Yes Parallel Support: No Parallel Degree: 1 Concurrent DML: No Possible blocked MDLs: Error Msg: Suggest Info: Statement: EXPLAIN ALTER TABLE t1 modify COLUMN a char(1) 1 row in set (0.01 sec)- 结果显示,Algorithm字段值为COPY,表示修改列定义操作仅支持COPY算法;Metadata Only字段值为No,表示修改列定义操作需要发生数据重建; Concurrent DML字段值为No,表示修改列定义操作不支持并发的DML访问。此类DDL操作对业务影响较大,需要谨慎执行。 
- 对重建表操作进行EXPLAIN: - EXPLAIN ALTER TABLE t1 engine= innodb;- 执行结果如下: - *************************** 1. row *************************** Error No: 0 Algorithm: INPLACE Metadata Only: No Rebuilt table: Yes Parallel Support: Yes But Not Enable Parallel Degree: 1 Concurrent DML: Yes Possible blocked MDLs: Error Msg: Suggest Info: 1. This DDL operation could use Parallel DDL to speed up. Statement: EXPLAIN ALTER TABLE t1 engine= innodb- 结果显示,Algorithm字段值为INPLACE,表示重建表操作支持INPLACE算法;Rebuilt Table字段值为Yes,表示重建表操作需要重建全表数据;Concurrent DML字段值为Yes,表示重建表操作支持并发的DML访问。此类DDL操作虽然执行期间支持业务访问,但是由于全表重建会消耗较多数据库资源,因此建议在业务低峰期执行。 
查询当前DDL操作是否支持并行DDL加速
PolarDB MySQL版支持使用并行DDL功能对DDL操作进行加速。借助于EXPLAIN DDL执行结果中的Parallel Support和Parallel Degree字段,可以了解当前DDL操作是否支持使用并行DDL功能进行加速。
- 若当前DDL操作支持并行DDL,但是集群未开启并行DDL功能,Suggest Info字段会展示如下提示信息This DDL operation could use Parallel DDL to speed up.,此时,您可以参见并行DDL开启并行DDL功能。 
- 若当前DDL操作支持并行DDL,且集群已开启并行DDL功能,EXPLAIN DDL会根据当前集群的负载,给出推荐的并行度配置。此时Suggest Info字段展示的提示信息如下This DDL operation can be accelerated by increasing the value of 'innodb_polar_parallel_ddl_threads'.The recommended value is 8. 您可以参见提示的并行度对 - innodb_polar_parallel_ddl_threads参数进行调整,以获取更大的加速效果。
下面展示了两个执行示例:
- 关闭并行DDL功能,对添加二级索引操作进行EXPLAIN: - MySQL [test]> SHOW variables LIKE "%parallel_ddl_threads%"; +----------------------------------------------------+-------+ | Variable_name | Value | +----------------------------------------------------+-------+ | innodb_polar_innovate_default_parallel_ddl_threads | 1 | | innodb_polar_parallel_ddl_threads | 1 | +----------------------------------------------------+-------+ 2 rows in set (0.03 sec)- 结果显示,当前集群暂未开启并行DDL功能。此时,对添加二级索引操作进行EXPLAIN: - EXPLAIN ALTER TABLE t1 ADD index k_a(a);- 结果如下: - *************************** 1. row *************************** Error No: 0 Algorithm: INPLACE Metadata Only: No Rebuilt table: No Parallel Support: Yes But Not Enable Parallel Degree: 1 Concurrent DML: Yes Possible blocked MDLs: Error Msg: Suggest Info: 1. This DDL operation could use Parallel DDL to speed up. Statement: EXPLAIN ALTER TABLE t1 ADD index k_a(a) 1 row in set (0.01 sec)- 当关闭并行DDL功能时,对添加二级索引操作进行EXPLAIN。结果显示,Parallel Support字段值为Yes But Not Enable,表示虽然当前DDL操作支持使用并行DDL功能进行加速,但是由于集群并未开启并行DDL功能,因此,此DDL操作未实际使用并行DDL功能进行加速。同时,在Suggest Info字段中,也给出了建议开启并行DDL的提示。 
- 开启并行DDL功能,对添加二级索引操作进行EXPLAIN: - 将当前并行DDL的并行度设置为2: - MySQL [test]> SET innodb_polar_parallel_ddl_threads = 2 ; Query OK, 0 rows affected (0.00 sec)- 对添加二级索引操作进行EXPLAIN: - EXPLAIN ALTER TABLE t1 ADD index k_a(a);- 执行结果如下: - *************************** 1. row *************************** Error No: 0 Algorithm: INPLACE Metadata Only: No Rebuilt table: No Parallel Support: Yes Parallel Degree: 2 Concurrent DML: Yes Possible blocked MDLs: Error Msg: Suggest Info: 1. This DDL operation can be accelerated BY increasing the VALUE OF 'innodb_polar_parallel_ddl_threads'. The recommended VALUE IS 8. Statement: explain ALTER TABLE t1 ADD index k_a(a) 1 row in set (0.01 sec)
当开启并行DDL功能后,再次对添加二级索引操作进行EXPLAIN。此时可以看到 ,Parallel Degree字段值为2,表示当前DDL操作将使用2个线程执行。同时,由于当前集群负载较低,因此在Suggest Info字段中,给出了将并行度提升为8,以获得更大的加速效果的建议。
潜在的MDL阻塞检测
DDL在执行期间,如果目标表上存在未提交的事务,此时DDL操作会被阻塞。极端情况下可能会导致连接数堆积,进而导致集群发生“雪崩”。借助于EXPLAIN DDL执行结果中的Possible blocked MDLs字段,可以提前判断当前DDL操作是否存在潜在的锁阻塞问题。当存在潜在的锁冲突时,Possible blocked MDLs字段会列出未提交事务所在连接的Process ID。您可以使用KILL或KILL QUERY命令手动结束该事务,避免DDL操作被阻塞。
下面展示了一个简单的示例:在连接1中,对t1表进行访问,且未提交当前事务。此时在连接2中对t1表执行EXPLAIN DDL操作。在执行结果中,Possible blocked MDLs 字段列出了未提交事务所在连接的Process ID,同时在Suggest Info中也给出了相应的提示信息。
- Connection 1: - 对t1表进行访问,且未提交当前事务: - MySQL [test]> begin; Query OK, 0 rows affected (0.00 sec) MySQL [test]> select * from t1; Empty set (0.00 sec)
- Connection 2: - 对t1表执行EXPLAIN DDL操作: - EXPLAIN ALTER TABLE t1 engine= innodb; *************************** 1. row *************************** Error No: 0 Algorithm: INPLACE Metadata Only: No Rebuilt table: Yes Parallel Support: Yes But Not Enable Parallel Degree: 1 Concurrent DML: Yes Possible blocked MDLs: 18 Error Msg: Suggest Info: 1. This DDL operation may be blocked BY the threads listed under 'Possible blocked MDLs'. 2. This DDL operation could use Parallel DDL TO speed up. Statement: EXPLAIN ALTER TABLE t1 engine= innodb