【华为云MySQL技术专栏】TaurusDB新特性解读:非阻塞DDL

举报
GaussDB 数据库 发表于 2025/01/03 09:01:38 2025/01/03
964 0 0
【摘要】 1. 背景介绍用户在执行DDL(Data Definition Language,数据定义语言)操作的时候,如果目标表存在未提交的长事务或大查询,DDL将持续等待获取MDL-EXCLUSIVE(X)锁。在华为云TaurusDB中,由于MDL-X锁具有最高优先级,DDL在持续等待MDL-X锁的过程中,将阻塞目标表上所有的新事务,这将导致业务连接的堆积和阻塞,甚至可能会造成整个业务系统的崩溃。T...

1. 背景介绍

用户在执行DDL(Data Definition Language,数据定义语言)操作的时候,如果目标表存在未提交的长事务或大查询,DDL将持续等待获取MDL-EXCLUSIVE(X)锁。在华为云TaurusDB中,由于MDL-X锁具有最高优先级,DDL在持续等待MDL-X锁的过程中,将阻塞目标表上所有的新事务,这将导致业务连接的堆积和阻塞,甚至可能会造成整个业务系统的崩溃。

TaurusDB提供的非阻塞DDL【1】功能,确保了即使在无法立即获得MDL-X锁的情况下,也不会长时间阻塞后续对目标表的读写操作,避免用户读写事务长时间等锁,减少读写事务的时延,同时,避免了因阻塞事务集中执行而导致的性能抖动,从而保证整个数据库和业务系统的稳定。

2. 问题分析及实现原理

2.1 问题分析

TaurusDB采用元数据锁(MDL)来保护对数据库元数据的访问。在用户的DDL操作中,不可避免地会修改表的元数据信息。为了保证表结构和表数据的一致性,必须为所修改的目标表申请MDL-EXCLUSIVE(X)锁,来阻塞并发的元数据查询或者修改操作,确保所有并发线程用正确的元数据进行表数据的读写。

TaurusDB支持的MDL锁有MDL_SHARED(S)、MDL_SHARED_READ(SR)、MDL_SHARED_WRITE(SW)、MDL-EXCLUSIVE(X)等11种类型,其中,MDL-X锁具有最高的优先级和排他性【2】。对任何MDL加锁申请,需要满足两个条件,才能被授予锁:

条件1:当前表正在等待的MDL锁类型没有更高优先级的;

条件2:已经授予的 MDL锁类型没有与之不兼容的。

1 MDL请求类型与已授予类型的兼容性

如图1所示,MDL-X锁与所有其他类型的锁不兼容用户的目标表存在未提交的长事务或者大查询时,也就是已授予的MDL锁类型存在不兼容的锁,DDL就会因为不满足条件2,无法立即被授予MDL-X锁,必须等待,直到被成功授予,或者等待时间超过lock_wait_timeout设定的锁等待时限,仍未获取到锁,该DDL语句将触发失败并进行回滚。

2 MDL请求类型与等待中类型的优先级

如图2所示,MDL-X锁在锁等待队列中的优先级最高,在DDL等待MDL-X锁的过程中,如果有其他的SELECT操作需要申请MDL-SR锁,或者DML写操作需要申请MDL-SW锁,此时新的锁请求就会因为等待列表中有更高优先级的MDL-X锁,不满足条件 1而被阻塞。

由此可见,DDL持续等待获取MDL-X锁,将阻塞目标表上所有的新事务,这将导致业务连接的堆积和阻塞,甚至可能会造成整个业务系统的崩溃。

2.2 实现原理

如上所述,当DDL在等待获取MDL-X锁时,由于X锁具有最高的等待优先级,阻止了其它后续的DML,但是X锁又要一直等待,直到获取到或者超时。

要解决这个问题,TaurusDB从减少X锁排他性影响入手,优化了X锁的等待逻辑,将申请MDL-X锁的过程分为了两个阶段:申请锁阶段和Sleep阶段。

如果DDL操作无法在一个比较短的指定时间获取MDL-X锁,DDL线程就会进入Sleep阶段。在Sleep阶段,客户其他线程的读写操作可以正常执行,包括前一轮申请X锁过程中处于等锁状态的DML操作。Sleep阶段结束后,DDL会再次进入申请锁阶段,重试获取MDL-X锁。如果成功获取,则退出循环;如果失败,继续进入Sleep阶段。这一过程将持续循环,直到获取MDL锁,或者到达最大重试次数。

2.2.1 参数设置

非阻塞DDL特性提供四个参数供用户配置:

1)rds_nonblock_ddl_enable

使用该功能前,首先需要将开关rds_nonblock_ddl_enable设置为ON。如果要全局打开,请在TaurusDB控制台的“参数修改”页面修改rds_nonblock_ddl_enable参数为ON;如果只是想对某个DDL应用,可在DDL当前会话中执行set rds_nonblock_ddl_enable = ON,来打开session级别的开关。

2)rds_nonblock_ddl_lock_wait_timeout

获取MDL-X锁超时的时间,也就是申请锁阶段的等锁时长,超过这个时间, DDL就会放弃X锁申请,而进入Sleep睡眠状态。

3)rds_nonblock_ddl_retry_interval

获取MDL-X锁超时后等待重试的时间间隔,也就是DDL的Sleep睡眠阶段的时长。

4)rds_nonblock_ddl_retry_times

获取MDL-X锁的最大重试次数。当到达最大重试次数仍未获取到X锁,DDL会失败报错。

2.2.2 使用限制

当前非阻塞DDL也存在一些使用限制:

(1)非阻塞DDL特性,仅支持ALTER TABLE、RENAME TABLE、CREATE INDEX、DROP INDEX和OPTIMIZE TABLE语句。

(2)开启非阻塞DDL功能会导致DDL的优先级降低,同时因MDL锁获取失败而导致执行DDL的失败概率也会相应增大。

3. 使用方法

(1)在TaurusDB控制台或者DDL会话中开启非阻塞DDL开关,参数rds_nonblock_ddl_lock_wait_timeout、rds_nonblock_ddl_retry_interval和rds_nonblock_ddl_retry_times可以使用默认值,也可以根据用户业务需要设置,本文一律使用默认值。

(2)在目标表test1 上开启一个新事务但不提交,该事务持有目标表test1的MDL锁。

begin;
select * from test1;

(3)开启一个新会话,在开启非阻塞 DDL功能的条件下,对表test1进行加列操作, 可以看到 DDL一直在执行中。

alter table test1 add column d int;

(4)开启另一个新会话,对表test1执行DML操作,可以看到DML操作可以正常执行,不会被阻塞。

3非阻塞DDL开启关闭状态的执行效果对比

4、客户场景测试

使用SysBench模拟客户业务场景,测试开启和关闭非阻塞DDL特性对业务的影响。

(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的变化情况。参数rds_nonblock_ddl_lock_wait_timeout、rds_nonblock_ddl_retry_interval和rds_nonblock_ddl_retry_times均使用默认值。

alter table sbtest1 add column d int;

(5)观察测试结果。

关闭非阻塞DDL, TPS持续跌零。默认超时时间为31536000秒,严重影响用户业务。

4 关闭非阻塞DDL场景下,业务TPS掉零

开启非阻塞DDL, TPS周期性下降,在rds_nonblock_ddl_lock_wait_timeout(默认1s,用户可自定义)的短时间内,阻塞并发的DML,导致TPS下降;在rds_nonblock_ddl_retry_interval(默认6s,用户可自定义)时间内,不阻塞并发DML,TPS恢复正常。也就是说,DDL的MDL-X锁等待仅会影响rds_nonblock_ddl_lock_wait_timeout等锁时长内的DML操作,对用户业务的影响减少。

5 开启非阻塞DDL场景下,业务TPS未掉零

5总结

非阻塞DDL特性,解决了DDL在无法获得MDL-X锁的情况下,阻塞对目标表的其他后续DML操作的问题,能够尽可能地保证客户业务系统的稳定。本文从技术背景、实现原理、使用方法、客户场景测试等方面介绍了特性的使用方法和应用场景,希望能够对您有所帮助。

参考:

【1】 华为云TaurusDB非阻塞 DDL 使用指南

【2】【华为云 MySQL技术专栏】TaurusDB MDL实现机制解析

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。