MySQL MVCC机制
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/68
行结构
每一行额外包含三个隐藏字段:
- DB_TRX_ID:事务ID。行的创建时间和删除时间记录的就是此值。
- DB_ROLL_PTR:指向当前记录项的undo信息。
- DB_ROW_ID::随着新行插入单调递增的一个字段。当由innodb自动产生聚集索引时,聚集索引包括这个DB_ROW_ID的值,不然的话聚集索引中不包括这个值。
- 在insert操作时,创建时间 = DB_ROW_ID,这时,“删除时间 ”是未定义的。
- 在update操作时,复制新增行的“创建时间”=DB_ROW_ID,删除时间未定义,旧数据行“创建时间”不变,删除时间=该事务的DB_ROW_ID。
- 在delete操作时,相应数据行的“创建时间”不变,删除时间 = 该事务的DB_ROW_ID。
- select操作对两者都不修改,只读相应的数据。
Read View
dulint low_limit_id; /* 事务号 >= low_limit_id的记录,对于当前Read View都是不可见的 */
dulint up_limit_id; /* 事务号 < up_limit_id ,对于当前Read View都是可见的 */
ulint n_trx_ids; /* Number of cells in the trx_ids array */
dulint* trx_ids; /* Additional trx ids which the read should
not see: typically, these are the active
transactions at the time when the read is
serialized, except the reading transaction
itself; the trx ids in this array are in a
descending order */
dulint creator_trx_id; /* trx id of creating transaction, or
(0, 0) used in purge */
关于low_limit_id,up_limit_id的理解:
up_limit_id:当前已经提交的事务号 + 1,事务号 < up_limit_id ,对于当前Read View都是可见的。理解起来就是创建Read View视图的时候,之前已经提交的事务对于该事务肯定是可见的。
low_limit_id:当前最大的事务号 + 1,事务号 >= low_limit_id,对于当前Read View都是不可见的。理解起来就是在创建Read View视图之后创建的事务对于该事务肯定是不可见的。
另外,trx_ids为活跃事务id列表,即Read View初始化时当前未提交的事务列表。所以当进行RR读的时候,trx_ids中的事务对于本事务是不可见的(除了自身事务,自身事务对于表的修改对于自己当然是可见的)。理解起来就是创建RV时,将当前活跃事务ID记录下来,后续即使他们提交对于本事务也是不可见的。
example
| 步骤 | 1 | 2 | 3 |
|---|---|---|---|
| 一 | begin | ||
| 二 | begin | ||
| 三 | insert into test(score) values(1607); 假设此时事务号21 | ||
| 四 | insert into test(score) values(1607); 此时事务号22 | ||
| 五 | 此时创建读视图,up_limit_id = 21, low_limit_id = 23 活跃事务列表为(21,22) |
||
| 六 | insert into test(score) values(1620); 事务号为23 | ||
| 七 | insert into test(score) values(1621); 事务号为24 | ||
| 八 | insert into test(score) values(1622); 事务号为25 | ||
| 九 | select * from test; 此时的up_limit_id 为21,low_limit_id 为26,活跃事务列表为(21,22),故21,22在活跃事务列表不可见 ![]() |
||
| 十 | select * from test; 此时low_limit_id为26,up_limit_id 为21,活跃事务列表是(21,22) 22本事务自身可见。21的在活跃事务列表不可见。23,24不在活跃事务列表,可见 ![]() |
||
| 十一 | select * from test; 事务内readview不变,low_limit_id = 23,up_limit_id = 21,活跃事务列表 (21,22)。故21自身可见,22在活跃事务列表不可见。>=23的都不可见 ![]() |
注意的几点:
- Read View视图是在进行RR读之前创建的,而不是在事务刚
begin时创建的。如果Read View视图是在事务刚begin时创建的,那么在步骤四中事务22的Read View就定下来了(up_limit_id = 21,low_limit_id = 23),那么在步骤十中就看不到3中提交的数据了,因为事务号23,24,25大于等于事务22.low_limit_id - 事务内Read View一旦创建就不变化了。
- 在第十步中按我之前的理解,3中insert的数据是在2中begin之后插入的,按理说2是看不到3中insert插入的数据的。但是事务保证的是两次select的数据是一致的,所以Read View是在第一次select时创建的,所以3中insert的数据是在2中可以看到。
参考资料:http://hedengcheng.com/?p=148
MySQL MVCC机制的更多相关文章
- 轻松理解MYSQL MVCC 实现机制
轻松理解MYSQL MVCC 实现机制 转载https://blog.csdn.net/whoamiyang/article/details/51901888 1. MVCC简介 1.1 什么是MVC ...
- MySQL的MVCC机制
1.MVCC简介 1.1 MVCC是什么? MVCC,Multi-Version Concurrency Control,多版本并发控制.MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对 ...
- 一文读懂MySQL的事务隔离级别及MVCC机制
回顾前文: 一文学会MySQL的explain工具 一文读懂MySQL的索引结构及查询优化 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) 就软件开 ...
- MySQL多版本并发控制——MVCC机制分析
MVCC,即多版本并发控制(Multi-Version Concurrency Control)指的是,通过版本链维护一个数据的多个版本,使得读写操作没有冲突,可保证不同事务读写.写读操作并发执行,提 ...
- MySQL 学习笔记(二)MVCC 机制
之前在讲 MySQL 事务隔离性提到过,对于写操作给读操作的影响这种情形下发生的脏读.不可重复读.虚读问题.是通过MVCC 机制来进行解决的,那么MVCC到底是如何实现的,其内部原理是怎样的呢?我们要 ...
- mysql中innodb引擎的mvcc机制和BufferPool缓存机制
一.MVCC (1)mvcc主要undo日志版本链和read-view一致性视图来保证多事务的并发控制,mvcc是innodb的一种特殊机制,他保证了事务四大特性之一的隔离性(原子性,一致性,隔离性) ...
- MySQL 事务机制
事务处理是保证数据安全的重要机制,事务有四个重要属性 ,根据它们的英文名称可以记为ACID: 原子性(Atomic): 事务操作是不可分割的; 事务只存在已执行和未执行两种状态,不存在只执行了部分指令 ...
- mysql 缓存机制
了解mysql缓存吗(顺丰) mysql缓存机制就是缓存sql 文本及缓存结果,用KV形式保存再服务器内存中,如果运行相同的sql,服务器直接从缓存中去获取结果,不需要在再去解析.优化.执行sql. ...
- Sql Server Snapshot和mysql MVCC
mysql 在一个事务A中插入一条数据 在B事务中查询到的还是以前的数据,可以select *from table,不被锁住 Sql Server 默认级别 读已提交 所以A事务在 X表插入数据, ...
随机推荐
- RandomAccessFile多线程下载、复制文件、超大文件读写
最近在准备面试,翻了翻自己以前写的Demo,发现自己写了不少的工具包,今天整理了一下,分享给大家. 本文包含以下Demo: 1.常用方法测试 2.在文件中间插入一段新的数据 3.多线程下载文件 4.多 ...
- Git命令行对照表
git init # 初始化本地git仓库(创建新仓库) git config --global user.name "xxx" # 配置用户名 git config --glob ...
- Android - "cause failed to find target android-14" 问题
在导入别人的工程项目时经常会遇到各种问题,本文中的就是其中SDK不对导致的 在导入项目时已经修改了 两个build.gradle文件 错误的原因是后面中这两项没修改. compileSdkVers ...
- OpenStack搭建遇到的问题
前言:对于像我这种新手来说,搭建OpenStack真的很费劲,因为我总是每配置一个服务,我就想弄懂,后来搭建过程很累人,因此我想了个办法,等我搭建出来再学.我这里将记录我从开始之初到我学习,再到我毕业 ...
- UnityShader-菲涅尔反射(Fresnel Reflection)
菲涅耳公式(或菲涅耳方程),由奥古斯丁·让·菲涅耳导出.用来描述光在不同折射率的介质之间的行为.由公式推导出的光的反射称之为"菲涅尔反射".菲涅尔公式是光学中的重要公式,用它能解释 ...
- WinForm下的loading框实现
前言:在项目使用C/S模式情况下,由于需要经常进行数据的刷新,如果直接进行刷新,会有一个等待控件重画的过程,非常的不友好,因此在这里添加一个loading框进行等待显示. 实现:在经过多方面查询资料, ...
- 1.5 sleep()方法
方法sleep()的作用是在指定的毫秒数内让当前"正在执行的线程"休眠(暂停执行).这个"正在执行的线程"是指this.currentThread()返回的线程 ...
- Sagit.Framework For IOS 开发框架入门开发教程1:框架下载与环境配置
背景: 前天开源了框架:开源:Sagit.Framework For IOS 开发框架 所以注定要追补一套开发教程了,所以尽量抽空了!!! 步骤 1:下载框架源码 GitHub:https://git ...
- CSS的常见问题
1.css的编码风格 多行式:可读性越强,但是CSS文件的行数过多,影响开发速度,增大CSS文件的大小 一行式:可读性稍差,有效减少CSS文件的行数,有利于提高开发速度,减小CSS文件的大小 2.id ...
- db2服务器端授权
昨天吃饭回来有点晚,没有及时写,今天补上. db2服务器端安装就不说了,网上很多.今天具体说说授权吧.这是个麻烦事. 安装的时候会让你创建数据库.你就根据提 ...
此时创建读视图,up_limit_id = 21, low_limit_id = 23 活跃事务列表为(21,22)
