更新时间:2024-09-06 GMT+08:00

非阻塞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锁超时的时间。

表1 参数说明

参数名称

级别

描述

rds_nonblock_ddl_enable

Global,Session

非阻塞DDL功能开关。取值范围:

  • ON:开启非阻塞 DDL功能
  • OFF:关闭非阻塞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计算得到。

使用方法

  1. 使用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
  2. 通过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
  3. 在目标表sbtest1 上开启一个新事务但不提交,该事务持有目标表sbtest1的MDL锁。
    begin;
    select * from sbtest1;
  4. 开启一个新会话,在开启和关闭非阻塞 DDL功能的条件下,分别对表sbtest1进行加列操作,观察TPS的变化情况。
    alter table sbtest1 add column d int;
  5. 测试结果。
    • 关闭非阻塞DDL, TPS持续跌零。默认超时时间为31536000秒,严重影响用户业务。

    • 开启非阻塞DDL, TPS周期性下降,但未跌零,对用户业务影响较小。