【MySQL】InnoDB 事务锁源码分析
宋昭 https://kernelmaker.github.io/MySQL_Lock
【MySQL】InnoDB 事务锁源码分析
好久没写笔记了… InnoDB 事务锁这里的代码陆陆续续看过好几次,但一直没整理过。事务锁这玩意儿思想说起来其实就那么几句话,实现起来的代码却是又臭又硬的好大一坨,各种细节,不把这里啃明白的话在解决具体问题的时候有点虚,和别人讨论也感觉隔靴搔痒说不太透。刚好趁着假期下雨,整理一个源码阅读笔记,把那一坨加锁相关的代码提炼出来,记录一下。
本文前提:
代码MySQL 8.0.13
只整理Repeatable Read当前读。Read Committed简单很多,另外快照读是基于MVCC不用加锁,所以不在本文讨论范畴。
1. Lock 与 Latch
InnoDB 中的lock是事务中对访问/修改的record加的锁,它一般是在事务提交或回滚时释放。latch是在BTree上定位record的时候对Btree pages加的锁,它一般是在对page中对应record加上lock并且完成访问/修改后就释放,latch的锁区间比lock小很多。在具体的实现中,一个大的transaction会被拆成若干小的mini transaction(mtr),如下图所示:有一个transaction,依次做了insert,select…for update及update操作,这3个操作分别对应3个mtr,每个mtr完成:
1. 在btree查找目标record,加相关page latch;
2. 加目标record lock,修改对应record
3. 释放page latch