Author: yinggang.zyg
在MySQL生态中,DDL操作非常复杂,不仅耗时长、消耗硬件资源,而且涉及锁表操作,若操作不当可能会影响正常业务,甚至造成灾难性后果。此外,不同的DDL操作具有不同的执行特点,例如,添加字段不需要重建表,通常可以在秒级内完成,而修改字段类型则需要全表重建,并且在执行期间无法进行写操作。
为了帮助您深入了解和评估执行DDL所需的各方面信息,例如当前是否存在锁冲突、DDL操作是否需要重建表等,PolarDB MySQL版新增提供了EXPLAIN DDL功能。与EXPLAIN SQL类似,您可以在执行DDL前对DDL语句进行EXPLAIN,从而获取DDL操作的执行细节。
开启loose_polar_max_collect_thd_num_in_explain_ddl参数即可。
参数名 | 级别 | 说明 | |
---|---|---|---|
loose_polar_enable_explain_ddl | GLOBAL/SESSION | ON | OFF:总开关。控制是否开启EXPLAIN DDL功能。 |
loose_polar_max_collect_thd_num_in_explain_ddl | GLOBAL/SESSION [1, 512] |
控制收集的潜在MDL阻塞线程的数目。 |
{ EXPLAIN | DESCRIBE | DESC } ALTER TABLE ...
输出结果中,各个字段的含义如下:
字段 | 含义 | 取值范围 |
---|---|---|
Error No | 错误码。 |
0:执行成功。 other: 对应错误的错误码 |
Algorithm | 表示DDL将使用的执行算法。 |
Unknown:未知 Instant:使用INSTANT算法 Inplace:使用INPLACE算法 Copy:使用COPY算法 |
Metadata Only | 表示DDL是否仅需修改元信息,无需修改表中数据。 |
Unknown:未知 Yes:仅修改元数据 No:需要修改表中数据 |
Rebuilt table | 表示DDL是否需要表重建。 |
Unknown:未知 Yes:需要重建表 No:不需要重建表 |
Parallel Support | 表示是否支持并行DDL加速。 |
Unknown:未知 No :不支持 Not Need:无需修改数据,无需使用并行DDL加速 Yes:已启用并行DDL对当前DDL进行加速。 Yes But Not Enable:DDL操作支持并行DDL加速,但是并未开启并行DDL功能。 |
Parallel Degree | 当前DDL将使用的线程数。 |
-1:未知 [1-128]: DDL并行线程数 |
Concurrent DML | DDL期间是否支持并发读写。 |
Unknown:未知 Yes:支持并发读写 No:不支持并发读写 |
Possible blocked MDLs | 表示可能阻塞当前DDL操作的其他事务。此处记录其PROCESS ID。 |
由Process ID拼接的字符串。各个ID之间以逗号(,)分割。 |
Error Msg | 与Error No对应,表示当前DDL操作的错误信息。 | 字符串 |
Suggest Info | 当前DDL操作的建议信息。 | 字符串。包括但不限于如下内容: 1、当Possible blocked MDLs字段不为空时,提示解决潜在的锁冲突。 2、支持并行DDL时,给出相关调优参数,以进一步加速。 |
Statement | 当前语句。 | 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操作的执行示例:
MySQL [test]> 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)
MySQL [test]> explain alter table t1 add column d int \G
*************************** 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)
通过对加列操作进行EXPLAIN,结果显示,Algorithm字段值为INSTANT,表示加列操作支持INSTANT算法;Metadata Only字段值为Yes,表示加列操作仅修改元数据,无需表重建;Concurrent DML字段值为Yes,表示加列操作支持并发的DML访问。此类DDL可以秒级内完成,对业务影响较小。
MySQL [test]> explain alter table t1 rename t1_rn\G
*************************** 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)
通过对修改表名操作进行EXPLAIN,结果显示,Algorithm字段值为INPLACE,表示修改表名操作支持INPLACE算法;Metadata Only字段值为Yes,表示修改表名操作仅修改元数据,无需表重建; Concurrent DML字段值为Yes,表示修改表名操作支持并发的DML访问。此类DDL操作无需修改表中数据,对业务影响较小。
MySQL [test]> explain alter table t1 modify column a char(1) \G
*************************** 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)
通过对修改列定义操作进行EXPLAIN,结果显示,Algorithm字段值为COPY,表示修改列定义操作仅支持COPY算法;Metadata Only字段值为No,表示修改列定义操作需要发生数据重建; Concurrent DML字段值为Yes,表示修改列定义操作不支持并发的DML访问。此类DDL操作对业务影响较大,需要谨慎执行。
MySQL [test]> explain alter table t1 engine= innodb \G
*************************** 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
通过对重建表操作进行EXPLAIN,结果显示,Algorithm字段值为INPLACE,表示重建表操作支持INPLACE算法;Rebuilt Table字段值为Yes,表示重建表操作需要重建全表数据;Concurrent DML字段值为Yes,表示重建表操作支持并发的DML访问。此类DDL操作虽然执行期间支持业务访问,但是由于全表重建会消耗较多数据库资源,因此建议在业务低峰期执行。
PolarDB MySQL支持并行DDL功能对DDL操作进行加速。借助于Parallel Support和Parallel Degree字段,可以了解当前DDL是否支持并行DDL操作。
This DDL operation could use Parallel DDL to speed up.
This DDL operation can be accelerated by increasing the value of ‘innodb_polar_parallel_ddl_threads’. The recommended value is 8.
例如,当关闭并行DDL功能时,对添加二级索引操作进行EXPALIN 操作,可以看到,Parallel Support字段结果为Yes But Not Enable,意为虽然当前DDL操作支持并行加速,但是实例并未开启此功能,同时在Suggest Info中,也给出了建议开启并行DDL的提示。
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)
MySQL [test]> explain alter table t1 add index k_a(a)\G
*************************** 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功能后,再次对添加二级索引操作进行EXPALIN 操作,此时可以看到当前并行度为2。此时,由于当前实例负载较低,因此在Suggest Info中,建议将并行度提升为8,以获得更大的加速效果。
MySQL [test]> set innodb_polar_parallel_ddl_threads = 2 ;
Query OK, 0 rows affected (0.00 sec)
MySQL [test]> explain alter table t1 add index k_a(a)\G
*************************** 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在执行期间,如果目标表上存在未提交的事务,此时DDL操作会被阻塞。极端情况下可能会导致连接数堆积,进而导致实例发生”雪崩”。借助于EXPLAIN DDL执行结果中的Possible blocked MDLs字段,可以提前判断当前DDL操作是否存在潜在的锁阻塞问题。当存在潜在的锁冲突时,Possible blocked MDLs字段会列出未提交事务所在的线程ID。用户可以使用KILL 或 KILL QUERY命令手动结束该事务,避免DDL操作被阻塞。
例如:在连接1中,对t1表进行访问,且未提交当前事务。此时在连接2中对t1表执行EXPLAIN DDL操作。在执行结果中,Possible blocked MDLs 字段列出了未提交事务所在连接的Process ID,同时在Suggest Info中也给出了相应的提示信息。
connection 1:
MySQL [test]> begin;
Query OK, 0 rows affected (0.00 sec)
MySQL [test]> select * from t1;
Empty set (0.00 sec)
connection 2:
MySQL [test]> explain alter table t1 engine= innodb \G
*************************** 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