知识卡片
MySQL的锁分成服务器层和存储引擎层两套互相看不见的系统
内容
MySQL的可插拔存储引擎架构(见
[[MySQL可插拔存储引擎架构把查询处理与数据存储彻底解耦]])在锁机制上
延伸出一个直接后果:锁本身也被拆成了两套独立的系统。服务器层维护自己
的一套锁(最常见的是表锁:可以用LOCK TABLES显式获取,也可以由查询
执行过程隐式产生),完全独立于存储引擎自己实现的锁(比如InnoDB的行级
锁、间隙锁)。这两层锁在早期版本(MySQL 5.0及更早)里是互相不可见的:
服务器层根本不知道存储引擎内部发生了什么锁等待,因此排查锁竞争问题
时必须先分清楚”卡住的是服务器层的锁还是存储引擎层的锁”,才能找对
排查工具(SHOW PROCESSLIST只能看到服务器层的锁等待状态)。这两层锁
之间还有一层不那么直观的耦合:查询执行过程中,服务器层会自动创建和
释放”隐式锁”并传递给存储引擎,存储引擎收到后可能会把它”转换”成自己
内部的锁类型(比如InnoDB会把一个通用的服务器层表锁,按自己的规则
转换成特定类型的InnoDB表锁)——这个转换过程对操作者来说是不透明的,
从外部很难判断存储引擎内部实际持有的锁到底是什么形态。这个”两层锁、
早期版本互相看不见”的架构特点,直接解释了为什么MySQL的锁调试历史上
一直比单一存储引擎的数据库更棘手:排查者不仅要弄清楚是谁在等锁、
谁持有锁,还要先确认这把锁到底属于哪一层。
参考来源
- 位置:《高性能MySQL:第3版》附录E"锁的调试"(源文件:
_epub-src/OEBPS/Text/part0028.xhtml)
- 结论依据:原文明确"MySQL服务器本身使用了几种类型的锁……除了服务器
级别的锁,任何支持行级别锁的存储引擎,例如InnoDB,都实现了自己的锁。
在MySQL 5.0和更早版本中,服务器层无法主动识别这些锁,它们往往对
用户和数据库管理员不可见……存储引擎感知到后,可能会'转换'这些锁……
这也使得操作人很难理解InnoDB幕后到底做了什么",直接说明服务器层
锁与存储引擎层锁的分离及隐式锁转换的不透明性。
- 原始内容:除了服务器级别的锁,任何支持行级别锁的存储引擎,例如
InnoDB,都实现了自己的锁。在MySQL 5.0和更早版本中,服务器层无法
主动识别这些锁,它们往往对用户和数据库管理员不可见。