暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

产品解读 | GreatDB特性——非阻塞式DDL

万里数据库 2025-03-28
214

安全数据库GreatDB作为万里数据库自主研发的一款核心数据库产品,于2023年底首批通过安全可靠测评,可根据用户需求选择集中式或分布式部署。


GreatDB拥有哪些特性?解决了用户哪些痛点难题?


基于此,万里数据库悉心推出【产品解读】专栏,将从非阻塞式DDL、读写分离、备份方式等多个维度深入阐述GreatDB产品特性,帮您了解并用好GreatDB~


01

痛点说明


运维MySQL开源数据库的DBA,一般都有被MDL锁阻塞的经历。


DDL会申请操作对象的独占MDL锁,如果不能立即获得独占MDL锁,DDL的锁申请会进入该对象MDL的锁申请队列,后续所有该对象上的操作由于也要先申请MDL锁。


因此,这些锁申请也会进入到锁申请队列,排在DDL锁申请之后,导致该对象上的所有后续操作(包括DML操作和select)都被阻塞



02

万里数据库GreatDB解决方案


针对DBA的上述痛点,GreatDB给出了自己的解决方案,增加了非阻塞式DDL功能


在 lock_wait_timeout 定义时间内,DDL操作的会话间歇性申请独占MDL锁,在多次申请的间隙(200ms)会释放锁资源,允许新事务获取该对象的DML锁,从而提高数据库并发性。


GreatDB为非阻塞式DDL功能新增2个会话变量:

•lock_ddl_polling_mode

控制是否启用非阻塞式DDL特性,默认值:OFF,Global和Session级变量,可动态修改;


•lock_ddl_polling_runtime

每次尝试获取独占MDL锁的持续时长,单位:毫秒,默认值:1000 ;Global和Session级变量,可动态修改。



03

实验验证


在MySQL8.0.32和GreatDB6.1.1下,参数lock_wait_timeout都设置为600秒,使用DDL操作drop index构造DDL锁请求,观察MySQL的表现,并对比GreatDB非阻塞式DDL的表现。


3.1 MySQL的DDL锁表现


会话A

会话B

会话C

mysql> begin;
Query OK, 0 rows affected (0.01 sec)

mysql> update test1 set c='ccc' where id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
<<事务未提交,持有共享




mysql> alter table test1 add index idx_k(k);
<<无法获取独占MDL锁,被会话A阻塞,进入等待队列




mysql> select count(*) from test1;
<<共享MDL锁请求进入等待队列,排在会话B锁请求之后
<<无法获取共享MDL锁,被会话B阻塞


<<DDL语句中断或超时退出




<<会话获取MDL锁
+----------+
| count(*) |
+----------+
|       10 |
+----------+
1 row in set (8 min 0.34 sec)


MySQL会话C被阻塞的分析


•会话 B 的 DDL 被阻塞:

○DDL需要独占MDL锁,但会话A的未提交事务仍持有共享MDL锁。

○会话B进入MDL锁等待队列,直到会话A释放共享锁。


•会话 C 的 SELECT 阻塞:

○MySQL的MDL锁机制采用写锁优先策略:当有排他锁请求等待时,后续共享锁请求需等待独占锁获取后释放。

○会话C的SELECT需要共享MDL锁,但此时会话B的独占锁请求已处于等待队列中。根据锁优先级,会话C会被阻塞,直到会话B释放MDL锁。


3.2 GreatDB非阻塞式DDL表现

修改数据库的全局变量,启用非阻塞DDL功能。

##--启用非阻塞式DDL特性
greatdb> set global lock_ddl_polling_mode=on;
Query OK, 0 rows affected (0.00 sec)

##--每次尝试获取独占MDL锁持续100ms
greatdb> set global lock_ddl_polling_runtime=100;
Query OK, 0 rows affected, 1 warning (0.00 sec)


会话1

会话2

会话3

greatdb> begin;
Query OK, 0 rows affected (0.01 sec)

greatdb> update test1 set c='ccc' where id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
<<事务未提交,持有共享MDL锁




greatdb> alter table test1 add index idx_k(k);
<<无法获取独占MDL锁,DDL被阻塞
<<间歇性申请独占MDL锁,等待间隙放行后续共享MDL锁申请




greatdb> select count(*) from test1;
+----------+
| count(*) |
+----------+
|       10 |
+----------+
1 row in set (0.03 sec)
<<可以获得共享DML锁,不会阻塞,执行成功


GreatDB会话C未被阻塞的分析

会话B的DDL被阻塞:

  • DDL申请独占MDL锁,但会话A的未提交事务仍持有共享MDL锁,无法立即获得独占MDL锁。

  • 会话B进入表test1的MDL锁等待队列,设置超时时间lock_ddl_polling_runtime(100ms),超时后退出,等待200ms后,再次进入锁等待队列,循环执行。

  • 检查总等待时间,未超过 lock_wait_timeout时,继续上述循环,否则DDL超时退出。


会话 C 的 SELECT 阻塞:

会话C的SELECT需共享MDL锁,但此时会话B的DDL排他锁请求可能处于以下情况:

  • 在等待队列中。由于会话B的申请间歇性退出等待队列,会话C获取共享MDL锁,完成select操作;

  • 不在等待队列中(在200ms的等待时间),会话C获取共享MDL锁,完成select操作。


04

总  结


GreatDB通过非阻塞式 DDL 功能,使DDL操作的会话间歇性申请独占MDL锁,在申请的间隙会释放锁资源,允许新事务获取该对象的DML锁,从而完成MDL和select操作,彻底解决了困扰DBA的MDL锁阻塞问题。




项目纪实 | 版本升级操作get!GreatDB分布式升级过程详解

技术干货 | GreatDB新一代读写分离架构,如何炼就近乎0损耗的性能?

性能评测 | GreatDB VIP PLUGIN方案 VS MySQL InnoDB Cluster高可用方案

关于万里数据库


北京万里开源软件有限公司(简称“万里数据库”)成立于2000年,是专注于国产自主可控数据库产品研发的国家高新技术企业、国家级专精特新“小巨人”企业,拥有发明专利、软件著作权百余项。


万里数据库的技术底蕴源自对底层核心代码的掌控,产品始终坚持以“极致稳定、极致性能、极致易用”为目标,经过20余年的研发经验积累,产品在功能、性能、稳定、易用等方面均处于行业领先水平,广泛应用于金融、运营商、能源、政府、交通等行业重要业务系统中的超2000个业务场景,得到了用户和市场的认可与肯定。


2021年,公司创立GreatSQL开源社区,通过对MySQL技术的优化,目前已成长为国内活跃的自主开源数据库社区


极致稳定  极致性能  极致易用


“在看”点一下,万里早知道

文章转载自万里数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论