本文对PolarDB-X中的DDL的并行特性及参数控制进行详细说明。
前提条件
物理执行DDL并发控制在5.4.15-16715927版本后支持。
逻辑执行DDL并发控制在5.4.16-16825599版本后支持。
注意事项
采用本文描述的参数增大DDL的资源占用时,可能影响到同一时间的业务流量,因而需要确认业务的实际需求和集群资源规格满足需要方可启用。
概述
PolarDB-X中的DDL分为物理执行和逻辑执行两种实现方式,对于上述两类执行方式的特征以及不同种类DDL的执行方式请参见Online DDL。对于以上两类执行方式的DDL,PolarDB-X提供不同的参数控制机制,允许用户控制DDL占用资源和处理数据的吞吐量。
对于物理执行的DDL,CN进行物理表级别的物理DDL转发,主要的资源开销存在于DN上,PolarDB-X提供物理DDL请求并行度的相关控制参数。
对于逻辑执行的DDL,CN处理DDL全流程中的数据回填、多写、校验、元信息管理等全部逻辑,其中数据回填占据了绝大部分资源及时间,PolarDB-X提供逻辑执行中数据回填并行度的相关控制参数。
物理执行DDL并行控制
对于物理执行的DDL,通过下面的参数可以控制转发物理DDL请求的并行度:
参数 | 类型 | 级别 | 说明 | 默认值 | 最大配置建议 |
MERGE_DDL_CONCURRENT | bool | Session/Global | 是否并行发送物理DDL | false | 设置为true |
MERGE_CONCURRENT | bool | Session/Global | 是否在分库上并行建连 | false | 设置为true |
PREFETCH_SHARDS | int | Session/Global | 所有物理库上物理DDL请求的最大并行度 | 1*dn数量 | 最大设置为dn核数*dn数量① |
①默认情况下,单个物理DDL可以在DN单核上达到较高占用率,因而PREFETCH_SHARDS的值超出所有DN的核数时,继续增大该值的效果不显著。
以一个16C64G规格的2CN 2DN的实例为例,对TPCC 10000仓的表bmsql_order_line加本地索引的操作为例,在实例资源充裕的情况下可进行下面的参数设置:
/*+TDDL:cmd_extra(MERGE_DDL_CONCURRENT=true,MERGE_CONCURRENT=true,PREFETCH_SHARDS=32)*/
ALTER TABLE `bmsql_order_line` ADD LOCAL INDEX `i_ol_d_id`(`ol_d_id`);
通过show physical processlist where info like "%i_ol_d_id%";
,可以查看DN上并发执行的物理DDL情况。
逻辑执行DDL并行控制
对于逻辑执行的DDL,通过下面的参数可以控制数据回填的并发度及资源限制,同时可以通过show ddl status
观察逻辑执行进度。
针对添加GSI,repartition,OMC三类DDL的并行度控制参数:
参数 | 类型 | 级别 | 说明 | 默认值 | 最大配置建议 |
BACKFILL_PARALLELISM | int | Global | 全局允许的最大并发回填线程数 | max(CPU_cores, 8) * 4 | 一般无须调整 |
SLIDE_WINDOW_TIME_INTERVAL | int | Session/Global | 启动大物理表并发回填的延迟时间(秒) | 60 | 资源充足可调整为0 |
GSI_BACKFILL_PARALLELISM | int | Session/Global | 单个DDL Task中允许的最大并发回填线程数 | -1 | 一般无须调整 |
PHYSICAL_TABLE_BACKFILL_PARALLELISM | int | Session/Global | 单个物理表上允许的最大并发回填线程数 | 4 | 根据负载决定,最大可设置为CN核数*2 |
GSI_BACKFILL_SPEED_LIMITATION | int | Session/Global | 允许的最大回填速率(行/s) | 150000 | 根据负载决定,最大设置可设置为-1 |
针对move partition和扩缩容等DDL的并发度控制参数:
参数 | 类型 | 级别 | 说明 | 默认值 | 最大配置建议 |
BACKFILL_PARALLELISM | int | Global | 全局允许的最大并发回填线程数 | max(CPU_cores, 8) * 4 | 一般无须调整 |
SLIDE_WINDOW_TIME_INTERVAL | int | Session/Global | 启动大物理表并发回填的延迟时间(秒) | 60 | 资源充足可调整为0 |
SCALEOUT_BACKFILL_PARALLELISM | int | Session/Global | 单个DDL Task中允许的最大并发回填线程数 | -1 | 一般无须调整 |
PHYSICAL_TABLE_BACKFILL_PARALLELISM | int | Session/Global | 单个物理表上允许的最大并发回填线程数 | 4 | 根据负载决定,最大可设置为CN核数*2 |
SCALEOUT_BACKFILL_SPEED_LIMITATION | int | Session/Global | 允许的最大回填速率(行/s) | 300000 | 根据负载决定,最大设置可设置为-1 |
以在一个16C64G规格的2CN2DN的实例上,对TPCC 10000仓的表bmsql_order_line加全局索引的操作为例,默认参数设置情况下执行下面的语句:
/*+TDDL:cmd_extra(PURE_ASYNC_DDL_MODE=true)*/
ALTER TABLE `bmsql_order_line` ADD GLOBAL INDEX `g_i_ol_d_id`(`ol_d_id`) partition by hash(`ol_d_id`) partitions 32;
可通过show ddl status
观测实际的DDL执行状态:
show ddl status;
+----------------------------------+-----------+
| METRIC | VALUE |
+----------------------------------+-----------+
| BACKFILL_PARALLELISM | 32 |
| BACKFILL_ROWS_FINISHED | 288679866 |
| BACKFILL_ROWS_SPEED | 150186 |
| BACKFILL_TASK_FAILED | 0 |
| BACKFILL_TASK_FINISHED | 1 |
| BACKFILL_TASK_TOTAL | 0 |
| BACKFILL_TIME_MILLIS | 3450 |
| CHANGESET_APPLY_PARALLELISM | 0 |
| CHANGESET_APPLY_ROWS_SPEED | 0 |
| CHECKER_ROWS_FINISHED | 0 |
| CHECKER_TIME_MILLIS | 0 |
| DDL_EXECUTION_TIME_MILLIS | 696412 |
| DDL_JOBS_FINISHED | 5 |
| DDL_JOBS_TOTAL | 6 |
| DDL_TASK_FAILED | 4 |
| DDL_TASK_FINISHED | 107 |
| DDL_TASK_TOTAL | 63 |
| FASTCHECKER_TASK_RUNNING | 0 |
| FASTCHECKER_TASK_WAITING | 0 |
| FASTCHECKER_THREAD_POOL_MAX_SIZE | 1 |
| FASTCHECKER_THREAD_POOL_NOW_SIZE | 0 |
| FASTCHECKER_THREAD_POOL_NUM | 2 |
| THROTTLE_RATE | 150000 |
+----------------------------------+-----------+
其中值得关注的参数:
BACKFILL_PARALLESIM表示当前活跃的回填总线程数;
BACKFILL_ROWS_SPEED表示当前的回填按行统计的速度;
THROTTLE_RATE并表示限速。
此时的DDL回填速度受THROTTLE_RATE影响,限制在15万行/秒左右。如要达到最大并发度且取消限速,可采用下面的方式发送逻辑DDL。
/*+TDDL:cmd_extra(SLIDE_WINDOW_TIME_INTERVAL=0,PURE_ASYNC_DDL_MODE=true,PHYSICAL_TABLE_BACKFILL_PARALLELISM=8,GSI_BACKFILL_PARALLELISM=32,GSI_BACKFILL_SPEED_LIMITATION=-1)*/
ALTER TABLE bmsql_order_line ADD GLOBAL INDEX g_i_ol_d_id(`ol_d_id`) partition by hash(`ol_d_id`) partitions 32;
可通过show ddl status
可以观测实际的DDL执行状态:
show ddl status;
+----------------------------------+----------+
| METRIC | VALUE |
+----------------------------------+----------+
| BACKFILL_PARALLELISM | 32 |
| BACKFILL_ROWS_FINISHED | 37272038 |
| BACKFILL_ROWS_SPEED | 867669 |
| BACKFILL_TASK_FAILED | 0 |
| BACKFILL_TASK_FINISHED | 1 |
| BACKFILL_TASK_TOTAL | 0 |
| BACKFILL_TIME_MILLIS | 3450 |
| CHANGESET_APPLY_PARALLELISM | 0 |
| CHANGESET_APPLY_ROWS_SPEED | 0 |
| CHECKER_ROWS_FINISHED | 0 |
| CHECKER_TIME_MILLIS | 0 |
| DDL_EXECUTION_TIME_MILLIS | 112397 |
| DDL_JOBS_FINISHED | 3 |
| DDL_JOBS_TOTAL | 4 |
| DDL_TASK_FAILED | 2 |
| DDL_TASK_FINISHED | 75 |
| DDL_TASK_TOTAL | 42 |
| FASTCHECKER_TASK_RUNNING | 0 |
| FASTCHECKER_TASK_WAITING | 0 |
| FASTCHECKER_THREAD_POOL_MAX_SIZE | 1 |
| FASTCHECKER_THREAD_POOL_NOW_SIZE | 0 |
| FASTCHECKER_THREAD_POOL_NUM | 2 |
| THROTTLE_RATE | -1 |
+----------------------------------+----------+
23 rows in set (0.02 sec)
此时的DDL回填速度不受限制,在32个线程均处于运行状态的前提下,回填速度达到86万行/秒。
性能测试
PolarDB-X实例规格:16C64G,2个计算节点,2个存储节点。
表结构:TPCC,AUTO模式数据库,bmsql_order_line表。
CREATE TABLE `bmsql_order_line` ( `ol_w_id` int(11) NOT NULL, `ol_d_id` tinyint(4) NOT NULL, `ol_o_id` int(11) NOT NULL, `ol_number` tinyint(4) NOT NULL, `ol_i_id` int(11) NOT NULL, `ol_delivery_d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `ol_amount` decimal(6, 2) DEFAULT NULL, `ol_supply_w_id` int(11) DEFAULT NULL, `ol_quantity` int(11) DEFAULT NULL, `ol_dist_info` char(24) COLLATE latin1_bin DEFAULT NULL, PRIMARY KEY (`ol_w_id`, `ol_d_id`, `ol_o_id`, `ol_number`) ) ENGINE = InnoDB DEFAULT CHARSET = latin1 DEFAULT COLLATE = latin1_bin PARTITION BY KEY(`ol_w_id`) PARTITIONS 32
测试数据:可参照benchmark boot压测工具说明导入TPCC 10000仓数据,共计约30亿行数据,230 GB。
测试一:增加Local Index
设置参数执行下面的语句,通过show ddl
观察DDL执行状态:
/*+TDDL:cmd_extra(PURE_ASYNC_DDL_MODE=true,ENABLE_TWO_PHASE_DDL=false,ENBALE_DRDS_MULTI_PHASE_DDL=false,MERGE_DDL_CONCURRENT=true,MERGE_CONCURRENT=true,PREFETCH_SHARDS=xxx)*/
ALTER TABLE `bmsql_order_line` ADD LOCAL INDEX i_ol_o_id(ol_o_id);
在不同参数下执行时间与资源占用情况如下:
参数设置 | 执行时间(秒) | 并发加速比 | DN CPU平均使用率(<=核数) | DN IOPS平均使用率(<=1) |
PREFETCH_SHARDS=2(默认设置,单DN并发度为1) | 6880 | 1 | 135% | 55% |
PREFETCH_SHARDS=4(单DN并发度为2) | 3503 | 1.96 | 240% | 95% |
PREFETCH_SHARDS=8(单DN并发度为4) | 2514 | 2.69 | 470% | 100% |
PREFETCH_SHARDS=16(单DN并发度为8) | 2152 | 3.19 | 896% | 100% |
PREFETCH_SHARDS=32(单DN并发度为16) | 1954 | 3.52 | 1590% | 100% |
测试二:增加Global Index
设置参数执行下面的语句,通过show ddl status
观察DDL执行状态:
/*+TDDL:cmd_extra(PURE_ASYNC_DDL_MODE=true,SLIDE_WINDOW_TIME_INTERVAL=0,PHYSICAL_TABLE_BACKFILL_PARALLELISM=xxx,GSI_BACKFILL_SPEED_LIMITATION=xxx)*/ ALTER TABLE `bmsql_order_line` ADD GLOBAL INDEX `g_i_ol_o_id`(`ol_o_id`) PARTITION BY HASH(`ol_o_id`) PARTITIONS 32;
参数设置 | 执行时间(秒) | 并发加速比 | DN CPU平均使用率(<=核数) | DN IOPS平均使用率(<=1) | CN CPU平均使用率(<=核数) |
PHYSICAL_TABLE_BACKFILL_PARALLELISM=1, GSI_BACKFILL_SPEED_LIMITATION=150000(单物理表无并发,自动限速) | 17441 | 1 | 190% | 8% | 357% |
SLIDE_WINDOW_TIME_INTERVAL=0, PHYSICAL_TABLE_BACKFILL_PARALLELISM=4, GSI_BACKFILL_SPEED_LIMITATION=-1(默认设置但不限速) | 7124 | 2.45 | 594% | 23% | 723% |
SLIDE_WINDOW_TIME_INTERVAL=0, PHYSICAL_TABLE_BACKFILL_PARALLELISM=8, GSI_BACKFILL_SPEED_LIMITATION=-1(单物理表8个并发,无限速) | 4020 | 4.34 | 1175% | 54% | 1476% |