RDS MySQL支持非阻塞DDL(Non blocking DDL)功能,规避了DDL执行过程中因MDL锁长时间获取不成功导致的会话阻塞和连接堆积,提升DDL过程中实例的稳定性和可用性。
功能说明
背景:在MySQL中,DDL操作需要获取目标表的MDL-X锁,以确保元数据一致性。然而,当表上存在未提交事务或长查询时,DDL线程会因无法立即获取锁而进入等待状态(pending)。由于MDL-X锁具有最高优先级,pending状态下的MDL-X锁会阻塞目标表后续的所有访问,引发会话阻塞、连接堆积和响应延迟等问题,严重时可能导致整个业务系统不可用。
简介:RDS MySQL的非阻塞DDL通过修改DDL线程获取和等待MDL锁的策略,将“一次性长等待”改为“间歇性短等待”。在等待间歇中,DDL线程会释放对MDL-X的请求,新会话允许访问目标表,避免了DDL线程长时间阻塞其他会话对目标表的访问。
适用范围
参数管理
参数说明
您可以通过loose_rds_nonblock_ddl_retry_interval和loose_rds_nonblock_ddl_lock_wait_timeout参数来控制和调整非阻塞DDL功能。开启非阻塞DDL功能后,DDL线程会间歇性多次尝试获取MDL锁,获取失败则释放MDL请求并陷入等待。
参数名称 | 说明 |
|
|
|
|
修改参数
访问RDS实例列表,在上方选择地域,然后单击目标实例ID。
在左侧导航栏中单击参数设置。
在可修改参数页签内搜索待修改参数,并配置参数值。
单击确定,然后单击提交参数,并在弹出的窗口中选择生效的时间段。
功能效果
测试方法
本文采用sysbench工具模拟数据库实例上的数据访问,对比开启与关闭非阻塞DDL功能时,执行DDL对业务的影响。具体测试步骤如下:
使用sysbench构建表并插入数据。
sysbench oltp_read_write --db-ps-mode=auto --percentile=95 --mysql-host=$HOST --mysql-port=$PORT --mysql-user=$USER --mysql-db=$DB --tables=1 --table-size=50 --threads=16 prepare启动sysbench压力测试模拟在线业务。
sysbench oltp_read_write --db-ps-mode=auto --percentile=95 --mysql-host=$HOST --mysql-port=$PORT --mysql-user=$USER --mysql-db=$DB --tables=1 --table-size=50 --threads=16 --report-interval=1 --time=100 run启动一个会话,在待执行的目标表上开启长事务,以阻塞后续的 DDL 操作。
SELECT SLEEP(60) FROM sbtest1 LIMIT 1;启动另一个会话,在关闭非阻塞DDL功能的情况下执行如下DDL操作,观察TPS变化。
ALTER TABLE sbtest1 ENGINE = InnoDB; -- 预期:该DDL线程由于无法获取MDL锁被阻塞。开启非阻塞DDL功能:设置
loose_rds_nonblock_ddl_retry_interval参数值为 6,loose_rds_nonblock_ddl_lock_wait_timeout参数值为1。执行相同的DDL操作,观察TPS变化。ALTER TABLE sbtest1 ENGINE = InnoDB; -- 预期:该DDL线程可以获取MDL锁,不会完全被阻塞
测试结果
关闭非阻塞DDL功能时,DDL线程无法获取MDL锁,会话被完全阻塞。
开启非阻塞DDL功能后,DDL线程可以间歇性地获取MDL锁,会话不会被完全阻塞,系统稳定性得到保障。

