MySQL MVCC(多版本并发控制)
概述
为了提高并发MySQL加入了多版本并发控制,它把旧版本记录保存在了共享表空间(undolog),当事务提交之后将重做日志写入磁盘(前提innodb_flush_log_at_trx_commit为1)清空undolog,在5.6版本之后unodlog可以独立出共享表空间,引入MVCC的目的就是减少锁的挣用,通过阅读高性能mysql这本书的解释是MVCC是行级锁的一个变种,使大多数的读操作可以不用加锁,写操作也只锁定必要的行。。
正文
多版本并发控制只针对innodb的repeatable read和read committed这两种隔离级别。多版本并发控制的原理就是在每个记录行后面增加两个标示列用来存储该行的状态,分别存储改行的新系统版本号和删除系统版本号。系统的版本号会随着每增加一个事务递增。
TABLE
ID |
NAME |
Trx_id |
De_Trx_id |
1 |
a |
1 |
|
有四个事务:select(trx=2),insert(trx=3),delete(trx=4),update(trx=5)
现在这四个事务同时对该行进行操作,演示SELECT的可重复读,假设四个操作在SLECT提交之前都未提交,当然SELECT是能查看到四个操作的记录的。
SELECT:
SELET会根据以下两个条件去查找记录,下面两个条件需要同时满足:
1.只查找行的系统版本号小于或等于当前事务版本号的记录行。
2.删除版本号为空或者大于当前事务版本号的记录行。
BEGIN TRAN SELECT NAME FROM TABLE WHERE ID=1
ID |
NAME |
Trx_id |
De_Trx_id |
1 |
a |
1 |
|
WAIT 10 MINUTE SELECT NAME FROM TABLE WHERE ID=1
COMMIT
ID |
NAME |
Trx_id |
De_Trx_id |
1 |
a |
1 |
4 |
根据SELECT 的查找条件INSERT记录的事务版本号大于当前版本号所以不会被查到;DELETE的事务删除版本号大于当前版本号,所以该行会被查出;UPDATE第一行的事务的版本号小于当前版本号而删除版本号大于当前版本号,可以被查到,第二行因为事务版本号大于当前版本号所以不满足,最终SELECT查询的记录是UPDATE操作的第一条记录;SELECT两次查询的结果一致,满足可重复读隔离级别。当然在这里除了INSERT操作,其它的操作都无法在SELECT提交之前提交。
INSERT:
INSERT INTO TABLE(ID,NAME) VALUES(2,'B');
ID |
NAME |
Trx_id |
De_Trx_id |
2 |
b |
2 |
|
DELETE:
DELETE FROM TABLE WHERE ID=1;
ID |
NAME |
Trx_id |
De_Trx_id |
1 |
a |
1 |
3 |
UPDATE:
BEGIN TRAN UPDATE TABLE SET NAME='B' WHERE ID=1 COMMIT
ID |
NAME |
Trx_id |
De_Trx_id |
1 |
a |
1 |
4 |
ID |
NAME |
Trx_id |
De_Trx_id |
1 |
b |
4 |
|
注意:多版本并发控制不支持myisam存储引擎。
总结
在缓存中有一个用于维护锁的资源,对锁的维持需要消耗mysql的资源,多版本并发控制它就是减少了用于维持锁资源的消耗来提高性能,所以日志的写操作都是先undo再redo。
备注: 作者:pursuer.chen 博客:http://www.cnblogs.com/chenmh 本站点所有随笔都是原创,欢迎大家转载;但转载时必须注明文章来源,且在文章开头明显处给明链接。 《欢迎交流讨论》 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端