知识卡片

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和更早版本中,服务器层无法 主动识别这些锁,它们往往对用户和数据库管理员不可见。