非阻塞DDL
用户在执行DDL操作的时候,如果目标表存在未提交的长事务或大查询,DDL将持续等待获取MDL-X锁。在GaussDB(for MySQL)中,由于MDL-X锁具有最高优先级,DDL在等待MDL-X锁的过程中,将阻塞目标表上所有的新事务,这将导致业务连接的堆积和阻塞,可能会造成整个业务系统崩溃的严重后果。GaussDB(for MySQL)提供的非阻塞DDL功能,可以保证即使在无法获得MDL-X锁的情况下,依然允许新事务进入目标表,从而保证整个业务系统的稳定。
前提条件
内核版本为2.0.54.240600及以上版本支持使用该功能。
使用须知
- 开启非阻塞DDL功能会导致DDL的优先级降低,同时因MDL锁获取失败从而导致执行DDL的失败概率也会相应增大。
- ALTER TABLE、RENAME TABLE、CREATE INDEX、DROP INDEX和OPTIMIZE TABLE语句支持非阻塞DDL功能。
参数说明
您可以先使用“rds_nonblock_ddl_enable”参数开启非阻塞DDL功能,然后通过“rds_nonblock_ddl_retry_times”参数设置获取MDL-X锁超时重试的次数,“rds_nonblock_ddl_retry_interval”参数设置获取MDL-X锁超时重试的时间间隔,“rds_nonblock_ddl_lock_wait_timeout”参数设置获取MDL-X锁超时的时间。
参数名称 |
级别 |
描述 |
---|---|---|
rds_nonblock_ddl_enable |
Global,Session |
非阻塞DDL功能开关。取值范围:
默认值:OFF |
rds_nonblock_ddl_lock_wait_timeout |
Global,Session |
设置获取MDL-X锁超时时间,取值范围1~31536000,单位为秒,默认值为1。 |
rds_nonblock_ddl_retry_interval |
Global,Session |
设置获取MDL-X锁重试的时间间隔,取值范围1~31536000,单位为秒,默认值为6。 |
rds_nonblock_ddl_retry_times |
Global,Session |
设置获取MDL-X锁的重试次数,取值范围0~31536000,默认值为0。 当值为0时,由参数lock_wait_timeout和rds_ddl_lock_wait_timeout的较小值计算得到,对于不支持参数rds_ddl_lock_wait_timeout的语句,由lock_wait_timeout计算得到。 |
使用方法
- 使用SysBench创建1个测试表sbtest1, 并插入1000000行数据。
./oltp_read_write.lua --mysql-host="集群地址" --mysql-port="端口号" --mysql-user="用户名" --mysql-password="用户密码" --mysql-db="sbtest" --tables=1 --table-size=1000000 --report-interval=1 --percentile=99 --threads=8 --time=6000 prepare
- 通过SysBench中的oltp_read_write.lua模拟用户业务。
./oltp_read_write.lua --mysql-host="集群地址" --mysql-port="端口号" --mysql-user="用户名" --mysql-password="用户密码" --mysql-db="sbtest" --tables=1 --table-size=1000000 --report-interval=1 --percentile=99 --threads=8 --time=6000 run
- 在目标表sbtest1 上开启一个新事务但不提交,该事务持有目标表sbtest1的MDL锁。
begin; select * from sbtest1;
- 开启一个新会话,在开启和关闭非阻塞 DDL功能的条件下,分别对表sbtest1进行加列操作,观察TPS的变化情况。
alter table sbtest1 add column d int;
- 测试结果。