在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版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字段值为Yes,表示修改列定义操作不支持并发的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