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

包拯断案 | 当DDL与DML互相阻塞 如何缉拿归案@还故障一个真相

万里数据库 2025-01-20
106

1


DBA的日常苦恼


日常工作中,你是否有这样的经历:非生产环境中,由于开发小伙伴不按套路出牌,DDL与DML并发执行,导致许多会话受到阻塞,大量会话出现等待元数据锁,数据库连接数激增。虽然生产环境要求操作规范,规定不在业务高峰期执行DDL操作,但有时因业务SQL执行慢,不得不紧急创建索引来提速,也会发起DDL。因此,当遇到DDL与DML互相阻塞这类问题时,应如何快速定位并解决问题呢?话不多说,直接上案例~


2


DBA线上故障演练场


包拯DBA小组成员偶遇,一起闲话聊家常~


王朝

大人,我们安全数据库GreatDB分布式支持ONLINE-DDL吗?

当然,这个功能在之前版本就已经支持了。

包拯

王朝

我咋听说上次展大哥在某某并行环境创建索引,引起了数据库连接数激增,CPU资源告警啦!

快说说,展哥犯啥错误了,我们也吸取一下教训。

马汉


此时,展昭正好走进来听到对话,面露不悦之色……


包拯

既然你们都好奇,那今天就对此问题做一次故障演练,方便你们在遇到问题时果断处理解决。展昭,你负责给王朝马汉出题,让他俩来解决。

得令!

展昭


展昭冲王朝马汉一挑眉,开始一顿操作猛如虎,王朝马汉则在一旁密切关注着数据库集群环境的状态。

(一盏茶后)

王朝

大人,不好啦!集群现在很多会话出现Waiting for table metadata lock,活跃会话数一直在增长。



3


包拯初问

包拯

莫慌,看现象只在一个节点上有锁等待,当前集群全局元数据锁有哪些?

现在集群有一个DDL在执行,test.sbtest1表正在创建索引,应该是DDL阻塞了其他的DML操作。

王朝



马汉

不对呀,大人,您刚才不是说集群已经支持ONLINE DDL了吗?


4


包拯深思

包拯

别急着下结论,查询一下此表有关的DML会话状况,按时间排序展示。

大人,发现有一条慢SQL发生在此DDL操作前,且DDL语句状态是preparing alter table。

王朝



包拯捋了捋胡子、点点头,露出意料之中的神情。


包拯

去DN上查询此表的会话情况。

请看,DN上未发现创建索引的会话,但有一条LOCK TABLE会话信息。在此会话前,有一条sbtest1表相关的慢SQL。

王朝



5


包拯再问

包拯

你们觉得,这时最快的解决方法是什么?

我觉得应该KILL慢SQL,让DDL执行下去。

王朝

马汉

我认为应该在SN上KILL 掉创建索引的会话。

(摇了摇头)非也非也,别忘了自己的身份,我们是DBA,不能擅自做主KILL 业务SQL,而DDL失败了是可以重复执行的。

包拯


现在,SN已经向DN发送了LOCK TABLE指令,在SN上KILL会话已不是最佳时机。此时,最快的处理方式是KILL DN上LOCK TABLE的会话,让业务顺利进行,然后再跟应用小伙伴们讨论慢SQL是否需要KILL及优化的问题,告诉他们该慢SQL影响了DDL的执行,我们已终止了DDL会话,DDL不能与慢SQL同时执行。


(王朝马汉点点头,内心OS:大人高见。)


王朝

明白了大人,我立即处理DN上锁表的会话。


展昭听到此,露出一个意味不明的微笑,又啪啪啪操作了几下。

(片刻之后)


报错信息:集群又出现了Waiting for table metadata lock状态的大量会话,而且这次两个SN节点会话都受到影响,看来展大哥出组合拳了。但查看集群元数据锁,看到还是只有一个创建索引的DDL语句,也查看了DN上的会话,发现DDL会话状态为Waiting for table metadata lock,有一个慢SQL的执行耗时比DDL会话少13秒。



6


包拯沉思


包拯

当前集群会话中,是否有其他DDL操作?

除了创建索引的DDL外,又出现了两条创建触发器的会话。这两个会话发生在不同的SN节点上,而user属于内部用户system user。

王朝



包拯

用户是system user,说明是集群内部操作,这个会话动不得。这次业务慢SQL保不住了,把慢SQL语句记录下来,KILL掉慢SQL会话,同时在DN上KILL掉创建索引会话。

是,大人,我马上处理 。

王朝

马汉

大人英明,集群会话恢复正常了。

展护卫,我猜你刚才的操作是这样的:

包拯


第一次,用一个SN先发出一个慢SQL,然后在另一个SN上使用慢SQL相关的一个表,在上面创建索引。


第二次,用一个SN先发出创建索引命令,间隔13秒后在另一个SN上,在索引创建完成前发出了此表相关的一个慢SQL,继而又换了一个SN,发出一个创建触发器的指令。对与不对?


展昭

大人神算!但属下有两点不解,请您赐教:第一次操作中,您如何知道我换了一个SN创建索引,如果我仍连接相同的SN,在上面创建索引,处理方式会不同吗?

如果你创建索引与执行慢SQL连接相同的SN,在SN中会被拦截,SN会话状态将是Waiting for table metadata lock,而非Preparing alter table。DN上不会接收到LOCK TABLE的指令,此时在SN上KILL 创建索引的会话即可。

包拯

展昭

(点点头,恍然大悟)第二点,您如何知道我第二次操作连接了三个SN?

(会心一笑)是你创建的触发器露出了马脚,分别在两个节点上出现system user执行的创建触发器的会话,说明这两个节点在回放过程中都受到了阻塞,分别在等待慢SQL与创建索引的会话结束,所以我才说慢SQL与创建索引的操作都保不住了。因为不能动system user会话,动之会让SN节点状态变为ERROR,为了集群的稳定,只能牺牲慢SQL与创建索引的操作。

包拯

展昭+王朝+马汉

(齐声道)大人就是大人,我等佩服。

别拍马屁了,展护卫做一下本次故障演练的总结吧。

包拯


7


展昭总结


1.慢SQL判断:集群支持在线创建索引,但开头和结尾需短暂获取两次元数据锁,慢SQL会对其造成阻碍,这个慢SQL有可能发生在创建索引之前,也有可能发生在创建索引过程中。要根据SN和DN的会话状态判断创建索引执行到哪一步,不同的步骤要采取不同的处理方式。


2.开发运维小伙伴不按套路出牌时:要尽快定位问题,尽己所能减少此类问题造成的伤害。因此,我们要了解数据库的原理与行为表现,遇到问题时,冷静果断地进行分析定位,该出手时立即出手。


3.最重要的一点:天下武功,唯快不破,数据库出问题,大多出在慢SQL上。因此,我们要经常对慢日志进行分析,发现慢SQL,对其优化。无论选择什么方式,或以空间换时间,或以并发资源换时间,总之要保证其能快速执行,才能避免数据库集群出问题。


8


故障寄语


出现故障并不可怕,可怕的是我们没有任何解决思路。如果这篇文章没有帮到你,请关注《包拯断案》专栏,期待下篇文章给你带来更多精彩干货




包拯断案 | MGR回放失败 该如何缉拿归案@还故障一个真相

包拯断案 | commit偶发延迟  如何缉拿归案@还故障一个真相

包拯断案 | 生产环境下数据库update误操作  如何进行数据恢复@还故障一个真相


关于万里数据库


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


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


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


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



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


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

评论