什么是 MySQL 锁等待?
本文基于 MySQL 8.0.32 源码,存储引擎为 InnoDB。
- 先排队
不管是加表锁,还是加行锁,如果不能立即获得锁,加锁事务都需要进入锁等待状态。
事务进入锁等待状态,需要用锁结构来排队。和立即获得锁时的锁结构一样,这个锁结构的各属性都已经初始化完成。不同之处在于,它被设置为等待状态。
表锁、行锁处于等待状态时,都不能共用锁结构,而是需要申请一个新的锁结构。
每个事务对象初始化时,会预先创建 8 个表锁结构、8 个行锁结构。
事务执行过程中加锁,需要申请新的锁结构时,如果预先创建的表锁结构、行锁结构还有空闲的,可以直接找一个对应的空闲锁结构来使用,没有空闲的,则需要创建一个对应的锁结构。
事务拿到新的锁结构之后,会把 type_mode
属性的第 9 位设置为 1,表示这个锁结构处于等待状态。
关于申请新的表锁结构、行锁结构的详细逻辑,以及各属性的初始化,可以看前面对应的文章,这里不再赘述。
锁结构的各属性初始化完成之后,加锁事务就具备加入排队大军的条件了。
多个事务对同一个表加表锁,每个事务都会申请一个表锁结构。这些表锁结构通过各自的 locks
属性形成一个链表,我们称之为 locks 链表。
对于表锁,锁结构加入表对象的 locks 链表的末尾,排队过程就开始了。
多个事务对同一个数据页中的记录加行锁,一个事务对多个数据页中的记录加行锁,也会申请多个行锁结构。
映射到 rec_hash 的数组中同一个单元的多个行锁结构,通过各自的 hash
属性形成一个链表。
处于等待状态的行锁结构,加入这个链表的末尾,排队过程也就开始了。
同一个事务创建的一个或多个表锁结构、一个或多个行锁结构,通过各自的 trx_locks
属性形成一个链表,我们称之为 trx_locks 链表。
不管是表锁结构,还是行锁结构,都需要加入 trx_locks 链表
。表锁结构会加入链表的头部,行锁结构会加入链表的末尾。
- 再登记
开始排队之后,跟着队伍慢慢前进,等轮到自己获得锁不就行了,又搞出来个登记,岂不是多此一举?
我们可以通过生活中的场景来理解一下为什么要弄个登记逻辑。
某个周六,小明去找 Tony 老师剪头发。
距店一步之遥时,打眼一看:咦?店里没什么人,来的正是时候。
正美着呢,到了店门口,有个热情的小哥出来迎接。
小哥笑着说:哥,来拿个号。
小明面露不悦之色,嘀咕道:都没什么人,还拿什么号?
小哥依然笑魇如花,解释说:今天人很多,要等挺长时间。好多人不想干等,拿了号排队,留下手机号之后,都去逛了。快轮到他们时,我就打电话通知他们来。
听小哥说完,小明也只好拿了号排队,留下手机号,逛去了(看!他拉着谁的手?)。
书归正传,和上面的场景一样,加锁需要等待时,也要先排个队,然后登个记。
锁等待的登记,当然不是留手机号了,而是找到一个 slot,再把加锁的相关信息记录到这个 slot 的对象中。
前面介绍锁模块的初始化时,我们知道了锁模块有个 waiting_threads
属性,指向一片内存区域。
这片内存区域有 srv_max_n_threads 个 slot,每个 slot 存放一个 srv_slot_t 对象。
锁等待时,InnoDB 会从 waiting_threads 指向的第一个 slot 开始遍历,碰到第一个空闲的 slot(in_use
属性值为 false),就登记上。
登记的主要步骤如下:
- slot 的 in_use 属性值修改为 true,表示这个 slot 不再空闲。
- 锁等待的超时时间保存到 wait_timeout 属性中,供后台线程检查锁等待超时使用。
- 修改 slot 的其它属性,不一一介绍了。
- 通知后台线程发生了锁等待。
完成以上步骤之后,登记过程就结束了。
- 坐等通知
登记完成之后,就可以坐等通知了吗?
别急,还有一件小小的情况需要做。
如果本次加的是行锁,InnoDB 还需要记录锁等待的开始时间,这个开始时间就是当前时间。
如果本次加的是表锁,不会记录锁等待的开始时间,因为 server 层触发 InnoDB 加表锁时,锁等待的开始时间由 server 层记录。
InnoDB 自己发起的加表锁操作,不计算锁等待消耗的时间,也就不需要记录开始时间了。
记录锁等待的开始时间这件小事完成了,就可以坐等通知了。
发生以下事件时,锁等待的事务会收到通知:
- 锁等待超时了。
- 其它事务释放锁时,当前事务获得了锁。
- 解决死锁时,当前事务被选择成为受害者。
- 总结
锁等待的流程比较简单,主要步骤如下:
- 申请一个锁结构,加入链表,开始排队。
- 找到一个空闲的 slot,把加锁的相关信息记录到这个 slot 的对象中,完成登记工作。
- 如果加的是行锁,还需要记录锁等待的开始时间。
- 坐等通知。
更多技术文章,请访问:https://opensource.actionsky.com/
关于 SQLE
SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。
✨ Github:https://github.com/actiontech/sqle
📚 文档:https://actiontech.github.io/sqle-docs/
💻 官网:https://opensource.actionsky.com/sqle/
👥 微信群:请添加小助手加入 ActionOpenSource

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
5% 消耗,6 倍性能:揭秘新一代 iLogtail SPL 日志处理引擎与 Logstash 的 PK
作者:阿柄 引言 在当今数据驱动的时代,日志收集和处理工具对于保障系统稳定性和优化运维效率至关重要。随着企业数据量的不断增加和系统架构的日益复杂,传统日志处理工具面临着性能、灵活性和易用性等多方面的挑战。Logstash 作为一款广受欢迎的开源日志收集与处理工具,早已广泛应用于各类 IT 环境。然而,随着需求的多样化和技术的发展,新一代日志处理解决方案------iLogtail [ 1] 应运而生。 近期,iLogtail 2.0 隆重推出了新功能 SPL 处理模式,进一步增强了日志处理的能力。在本文中,我们将深入探讨为何选择 iLogtail,以及它在 SPL 数据处理方面相较于 Logstash 有何独特优势。通过对比这两款工具的架构、性能以及功能,我们希望能够揭示 iLogtail 如何在日益复杂的日志处理需求中脱颖而出,帮助您做出明智的技术选择。 iLogtail & SPL 介绍 iLogtail 是阿里巴巴开源的日志采集工具,设计之初便针对大规模数据以及云原生场景进行了优化,旨在提供低延迟、高效率的日志收集解决方案。iLogtail 拥有轻量级、高性能、自动化配置...
- 下一篇
详解微服务应用灰度发布最佳实践
作者:子丑 本次分享是站在 DevOps 视角的灰度发布实践概述,主要内容包括以下四个方面: 第一,灰度发布要解决的问题; 第二,灰度发布的四种典型场景; 第三,如何把灰度发布融入到应用的研发流程中,即把灰度发布与 DevOps 工作融合; 第四,对于外部流量灰度场景,演示如何通过工具将其落地。 灰度发布想解决什么问题 1、传统软件研发的需求交付 在早期的金融、电信等软件研发时,是不存在灰度发布的概念的,因为他们大多是全量上生产,测试过程耗时很长,且测试的单元不是各个微服务,而是整个的系统,以保证业务到达生产阶段后要尽可能的安全,不产生安全风险。在这种情况下,当业务到达生产阶段后,要回退或撤销成本很高也很难实现。 因此,在传统软件的研发过程中,开发者大量的心智负担在于如何保证新版本进入生产阶段后风险足够低。 2、微服务架构下典型的需求交付流程 在微服务架构下,多数开发者工作于 Web 应用的研发场景,其需求的交付过程已经产生了巨大的变革。交付的单元变小,一次交付往往是一个或几个小需求,通常仅涉及到几个应用的改造,且这些改造无需同时上线,可以按需部署。如下图所示: 在收到业务方的需求后,...
相关文章
文章评论
共有0条评论来说两句吧...