MySQL metadata lock的前世今生(5.1=>5.7)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

最近有同事经常问到一些metadata lock相关的问题,就顺便理一下吧,主要是整理下相关的连接和文档,标题写的有点大 :-)

——————————–

最初为了解决著名的bug#989,在MySQL5.5中开始引入了meta data lock;mdl允许一个事务涉及到的表、库信息直到事务结束都被维持,这样如果一条事务内的某个STATEMENT完成后,其他session发出一条DDL就会被阻塞;这解决了DDL/DML并发导致的复制中断问题。

不过用过5.5的人都知道,这玩意儿实际上太令人讨厌了,尤其是那阴魂不散的“wait for global read lock”或者“wait for table lock”之类的。当备份时的大查询,再来个DDL,哐当~故障发生..直接堵死…

在我们的内部alisql-5.5版本中,我们使用的是和facebook类似的办法(好吧,就是我直接从fb port过来的),即增加接口替换掉flush tables with read lock, 只创建一个read view ,外加返回当前binlog位点;另外percona也实现了一种类似的办法来绕过ftwrl,具体点击文档连接以及percona的博客, 不展开说了。

MDL解决了bug#989,却引入了一个新的热点,所有的mdl对象由于存到全局对象里;对于热点,最正常的想法当然是对其进行分区,不过这也是Mark Callaghan在report了bug#66473后才加入的,当时Mark观察到MDL_map::mutex的锁竞争非常高,进而推动官方改变;

MySQL5.6.8版本,引入了新参数metadata_locks_hash_instances来控制对mdl hash的分区数(Rev:4350);

Oracle的QA dimitrik 对该特性的评测

不过后面的测试又发现哈希函数有问题,类似类似somedb.someprefix1….somedb.someprefix8的hash key值相同,都被hash到同一个桶下面了.相当于hash分区没生效。。。。坑!!具体怎么算的可以看bug#66473后面Dmitry Lenev的分析。

另外Mark也提出了质疑,innodb的hash计算函数比my_hash_sort_bin要更高效, Oracle的开发人员重开了个bug#68487来跟踪该问题,并在MySQL5.6.15对hash key计算函数进行优化,包括fix 上面说的hash计算问题(Rev:5459),使用MurmurHash3算法来计算mdl key的hash值,(有空看看几种hash函数到底哪个性能更好)

往后直到MySQL5.6.18版本都没有针对mdl部分的单独优化;很显然,后面也不会在5.6版本里出现了,因为mdl优化已经在5.7.4版本里展开了。包含3个worklog

1. WL#7304

简化DML操作对MDL锁的持有/释放;大体思路是把MDL锁拆分成两类,一类是DML的mdl(也成为unobtrusive lock),之间互相兼容,另一类是DDL的mdl(也称为obtrusive lock),与其他锁互斥;

针对DML的MDL,避免了复杂的锁检查和对m_waiting/m_granted链表的维护,改而使用计数器的方式来实现(称为fast-path);不过相应的对DDL的MDL锁的管理逻辑就变的复杂了。没有细看,貌似fast-path的mdl在遇到冲突时会进行转换,将其加入到m_granted列表中,并从m_fast_path_state移除

PATCH(Rev:7067Rev:7129

2. WL#7305

使用Lock free的hash对象来管理MDL;由于锁冲突被移除,因此metadata_locks_hash_instances及metadata_locks_cache_size在之后的版本中可能被弃用;

基本思路是使用LF_HASH(lock free hash, 而不是分区的hash)来实现MDL_MAP

PATCH(Rev:7249)

3. WL#7306

这个实际上是对WL#7304和WL#的进一步优化,针对dml的mdl锁(也就是所谓fast path),在检查冲突和释放时都需要施加m_rwlock锁,新的改进移除读写锁,改使用原子操作

PATCH(Rev:7586)

这三个worklog是在5.7.4版本中的主要影响性能的大改动之一,官方对MySQL5.7.4的测试数据,这部分的改进必然有所贡献。

后续的新的改进计划目前还没看到,现在worklog上的更新总要等到实现之后才会更新,让我们拭目以待吧…


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
SQL 监控 关系型数据库
MySQL Metadata Locking(MDL)机制的实现与获取机制分析
MySQL Metadata Locking(MDL)机制的实现与获取机制分析 为了满足数据库在并发请求下的事务隔离性和一致性要求,同时针对MySQL插件式多种存储引擎都能发挥作用,MySQL在Server层实现了 Metadata Locking(MDL)机制。这种机制可以灵活自定义锁的对象、锁的类型以及不同锁类型的优先级,甚至可以做到在系统不同状态时动态调整不同锁类型的兼容性。本篇文章将详细介绍MDL系统中的常用数据结构及含义,从实现角度讨论MDL的获取机制与死锁检测,以及在实践中如何监控MDL状态。
35 2
|
9月前
|
SQL 关系型数据库 MySQL
Mysql Lock Wait
Mysql Lock Wait
147 0
|
5月前
|
关系型数据库 MySQL 数据库
MySQL报错:Lock wait timeout exceeded; try restarting transaction
MySQL报错:Lock wait timeout exceeded; try restarting transaction
|
5月前
|
SQL 关系型数据库 MySQL
MySQL报错:1205 Lock wait timeout exceeded; try restarting transaction处理
MySQL报错:1205 Lock wait timeout exceeded; try restarting transaction处理
|
6月前
|
SQL 关系型数据库 MySQL
【MySQL异常】MySQL事务锁问题----lock wait timeout exceeded; try restarting transaction
【MySQL异常】MySQL事务锁问题----lock wait timeout exceeded; try restarting transaction
49 0
|
9月前
|
SQL 关系型数据库 MySQL
Mysql 异常:Lock wait timeout exceeded; try restarting transaction的解决办法
Mysql 异常:Lock wait timeout exceeded; try restarting transaction的解决办法
103 0
|
9月前
|
SQL 关系型数据库 MySQL
mysql Lock wait timeout exceeded; try restarting transaction解决方案
在测试程序时,打的断点怎么都跳不进去,console一直报 “Lock wait timeout exceeded; try restarting transaction”
108 0
|
11月前
|
SQL 存储 缓存
|
关系型数据库 MySQL 索引
MySQL InnoDB中的锁-插入意向锁(Insert Intention Lock)
MySQL InnoDB 插入意向锁 Insert Intention Lock
3070 0
MySQL InnoDB中的锁-插入意向锁(Insert Intention Lock)
|
SQL 关系型数据库 MySQL
mysql中lock tables与unlock tables(锁表/解锁)使用总结
mysql中lock tables与unlock tables(锁表/解锁)使用总结
280 0