天天看点

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

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

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

——————————–

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

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

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

简化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移除

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

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

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

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