三分钟了解MVCC(InnoDB如何实现可重复读和读已提交)
快照读和当前读
快照读
快照读是指读取数据时不是读取最新版本的数据,而是基于历史版本读取的一个快照信息(mysql读取undo log历史版本) ,
快照读可以使普通的SELECT 读取数据时不用对表数据进行加锁
当前读
当前读是读取的数据库最新的数据,当前读和快照读不同,因为要读取最新的数据而且要保证事务的隔离性,所以当前读是需要对数据进行加锁的
(update、delete、insert、select ....lock in share mode、select for update)
MVCC如何解决幻读?
快照读下,通过Read view的方式解决了幻读,本文主要介绍快照读下的的幻读解决方式
当前读下,需要使用间隙锁来解决幻读,但本质上当前读就是为了查最新数据
如 select * from xxx where id > 1 for update
Read view是什么?
InnoDB的快照读并非创建数据的完整备份,而是创建了一份事务id相关的数据快照,结合undo_log来实现整体数据的快照读
read view主要储存了下列4项数据的快照
trx_ids: 当前系统活跃(未提交)事务版本号集合。
low_limit_id: 创建当前read view 时当前系统最大事务版本号+1。
为什么不是当前事务版本号+1:事务开始时刻为当前事务版本号+1,但读已提交级别的后续查询会创建新的readview,所以实际储存的是最大事务版本号+1
up_limit_id: 创建当前read view 时“系统正处于活跃事务最小版本号”
creator_trx_id: 创建当前read view的事务版本号;
InnoDB如何实现可重复读和读已提交?
1)数据库已存记录
trx_id |
数据 |
undolog |
---|---|---|
0 |
id = 1; name = cjd1 |
|
0 |
id = 2; name = cjd2 |
2)trx_id=2 修改数据id=1的数据 name=cjd11
trx_id |
数据 |
undolog |
trx_id |
数据 |
undolog |
|
---|---|---|---|---|---|---|
2 |
id = 1; name = cjd11 |
0xxxxxxx |
→ |
0 |
id = 1; name = cjd1 |
|
0 |
id = 2; name = cjd2 |
读已提交场景
3)trx_id=3 开启查询,创建readview
trx_ids |
low_limit_id |
up_limit_id |
creator_trx_id |
---|---|---|---|
2,3 |
2 |
4 |
3 |
此时数据库数据为
trx_id |
数据 |
undolog |
trx_id |
数据 |
undolog |
|
---|---|---|---|---|---|---|
2 |
id = 1; name = cjd11 |
0xxxxxxx |
→ |
0 |
id = 1; name = cjd1 |
|
0 |
id = 2; name = cjd2 |
trx_id = 2
>= low_limit_id(处于活跃的最小版本号) 且
< up_limit_id(当前系统最大事务版本号+1)且
!=creator_trx_id(当前事务版本号) 但
in trx_ids(正在活跃的事务版本号内)
故此数据不可见,根据undolog指针找到上一条记录trx_id=0 < low_limit_id,故数据可见
故该查询最终得到的数据为
trx_id |
数据 |
undolog |
trx_id |
数据 |
undolog |
|
---|---|---|---|---|---|---|
2 |
id = 1; name = cjd11 |
0xxxxxxx |
→ |
0 |
id = 1; name = cjd1 |
|
0 |
id = 2; name = cjd2 |
4)trx_id=2 新增记录id =3; trx_id=4新增记录id=4
trx_id |
数据 |
undolog |
trx_id |
数据 |
undolog |
|
---|---|---|---|---|---|---|
2 |
id = 1; name = cjd11 |
0xxxxxxx |
→ |
0 |
id = 1; name = cjd1 |
|
0 |
id = 2; name = cjd2 |
|||||
2 |
id = 3; name = cjd3 |
|||||
4 |
id = 4; name = cjd4 |
5)trx_id=3 开启查询,创建readview
trx_ids |
low_limit_id |
up_limit_id |
creator_trx_id |
---|---|---|---|
2,3,4 |
2 |
5 |
3 |
新增的id=3与id=4,因为事务版本号处于活跃,故都对该次查询不可见
故该查询最终得到的数据为
trx_id |
数据 |
undolog |
trx_id |
数据 |
undolog |
|
---|---|---|---|---|---|---|
2 |
id = 1; name = cjd11 |
0xxxxxxx |
→ |
0 |
id = 1; name = cjd1 |
|
0 |
id = 2; name = cjd2 |
|||||
2 |
id = 3; name = cjd3 |
|||||
4 |
id = 4; name = cjd4 |
6)trx_id=4 修改id=4数据为name=cjd41,并提交事务,trx_id=3创建数据name=cjd5
trx_id |
数据 |
undolog |
trx_id |
数据 |
undolog |
|
---|---|---|---|---|---|---|
2 |
id = 1; name = cjd11 |
0xxxxxxx |
→ |
0 |
id = 1; name = cjd1 |
|
0 |
id = 2; name = cjd2 |
|||||
2 |
id = 3; name = cjd3 |
|||||
4 |
id = 4; name = cjd41 |
0xxxxxxx |
→ |
4 |
id = 4; name = cjd4 |
|
3 |
id = 5; name = cjd5 |
7)trx_id=3 开启查询,创建readview
trx_ids |
low_limit_id |
up_limit_id |
creator_trx_id |
---|---|---|---|
2,3 |
2 |
5 |
3 |
事务4提交后,数据name=cjd41 对事务3可见,name=cjd5事务号为创建者自身也可见,故最终查询得到的数据为
trx_id |
数据 |
undolog |
trx_id |
数据 |
undolog |
|
---|---|---|---|---|---|---|
2 |
id = 1; name = cjd11 |
0xxxxxxx |
→ |
0 |
id = 1; name = cjd1 |
|
0 |
id = 2; name = cjd2 |
|||||
2 |
id = 3; name = cjd3 |
|||||
4 |
id = 4; name = cjd41 |
0xxxxxxx |
→ |
4 |
id = 4; name = cjd4 |
|
3 |
id = 5; name = cjd5 |
可重复读场景
3)可重复读场景下,无论第几次查询均使用事务开启时创建的read view,但可以读到后续自身事务创建的数据
trx_ids |
low_limit_id |
up_limit_id |
creator_trx_id |
---|---|---|---|
2,3 |
2 |
4 |
3 |
故可重复读得到的查询结果为
trx_id |
数据 |
undolog |
trx_id |
数据 |
undolog |
|
---|---|---|---|---|---|---|
2 |
id = 1; name = cjd11 |
0xxxxxxx |
→ |
0 |
id = 1; name = cjd1 |
|
0 |
id = 2; name = cjd2 |
|||||
2 |
id = 3; name = cjd3 |
|||||
4 |
id = 4; name = cjd41 |
0xxxxxxx |
→ |
4 |
id = 4; name = cjd4 |
|
3 |
id = 5; name = cjd5 |
读已提交每次查询创建新的read view,可重复读使用的第一次创建的read view
这也是为什么可重复读能解决幻读,而读已提交不能解决幻读的原因
三分钟了解MVCC(InnoDB如何实现可重复读和读已提交)相关推荐
- MySQL可重复读和读已提交实现原理,深入理解MVCC。
1.隔离级别 MySQL中隔离级别分为4种,提未交读.读已提交.可重复读.串行化.同时MySQL默认隔离级别为可重复读. 图片 查看MySQL隔离级别 SELECT @@tx_isolation 设置 ...
- MVCC如何实现数据库读已提交和可重复读这两种隔离级别?
文章目录 隐藏列 undo log ReadView 读已提交和可重复读的实现 我们都知道Mysql有四种事务隔离级别: 读未提交 读已提交 可重复读 串行化 这四个隔离级别的特点就不多赘述了,这次主 ...
- MySQL是如何实现读已提交和可重复读的——MVCC原理
先来看一下MySQL的事务隔离级别: 隔离级别 脏读 不可重复读 幻读 读未提交 有 有 有 读已提交 无 有 有 可重复读 无 无 有 串行化 无 无 无 MySQL有四种隔离级别:读未提交.读已提 ...
- 909-MySQL的MVCC机制下,可重复读级别不能完全解决虚读
MySQL使用MVCC(Multi-Version Concurrency Control,多版本并发控制)机制,默认隔离级别是RR(可重复读).MySQL使用mvcc的RR级别,并不能解决幻读的问题 ...
- mysql 读已提交、可重复读原理(mvcc、readview)
https://blog.csdn.net/qq_41388308/article/details/88583968 readview的文章https://baijiahao.baidu.com/s? ...
- 「数据库架构」三分钟搞懂事务隔离级别和脏读
重要要点 仅凭ACID或非ACID来思考,还需要知道数据库支持的隔离级别. 标榜为"最终一致"的某些数据库可能返回与任何时间点不一致的结果. 一些数据库提供的隔离级别比您要求的更高 ...
- mysql 隔离级别 快照_「数据库架构」三分钟搞懂事务隔离级别和脏读
重要要点 仅凭ACID或非ACID来思考,还需要知道数据库支持的隔离级别. 标榜为"最终一致"的某些数据库可能返回与任何时间点不一致的结果. 一些数据库提供的隔离级别比您要求的更高 ...
- 计算机语言三分钟怎么写,普通话测试话题范文30篇万能语句全国普通话测试三分钟说话万能模板.doc...
普通话测试话题范文30篇万能语句全国普通话测试三分钟说话万能模板 普通话考试30个经典命题说话题目及范文 1.我的愿望(或理想) 我很小时候就有一个愿望,就是长大后当一名优秀的教师. 我喜欢当教师有几 ...
- 五分钟了解Mysql脏读、幻读、不可重复读、mvcc
点击上方关注 "终端研发部" 设为"星标",和你一起掌握更多数据库知识 首先对多事务并发的问题的思考 对 innodb引擎执行流程 和 buffer pool ...
最新文章
- tensorflow.python.framework.errors_impl.InvalidArgumentError: 2 root error(s) found.
- 目标检测--DSOD: Learning Deeply Supervised Object Detectors from Scratch
- linux centos yum 报错 [Errno 256] No more mirrors to try 解决方法
- 在Silverlight中绘制贝塞尔曲线
- Ubuntu镜像国内下载地址
- 超牛!读博期间,他以第一作者发表7篇文章
- wordpress忘记登录密码,更改域名的办法。
- [XJOI]noip44 T3还有这种操作
- DEDE织梦标签名称:{/dede:arclist} 详解
- pycharm关闭pytest模式
- 深入理解JVM专题目录
- 服务器至强系列cpu排行,至强系列cpu天梯图2020 英特尔至强cpu天梯图排名
- matlab:研究二阶系统中开环参数的影响
- 信息学奥赛一本通 1293:买书 | OpenJudge NOI 2.6 6049:买书
- 微信终于可以发送大文件了!
- 评分卡模型监控(后端分析)
- 交换机、路由器设备选型总结
- 与老婆大人书之‘欧阳先生’
- echart 热搜词云(字符云)的制作以及遇到颜色不会随即变得bug
- 解决Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING
热门文章
- 日本要把123万吨核污水排入太平洋,核威胁距离我们有多远?
- jmeter入门——第一个jmeter脚本
- 脱离.Net Framework运行doNet程序的简单方法
- mongodb 集群shard_MongoDBV3.0.7版本(shard+replica)集群的搭建及验证
- Studio 3T重置日期,达到重复试用的效果
- 4 种最安全的 MacBook 电池更换选项
- fedora mysql 开机启动服务_linux -- 启动时启动服务或者执行命令
- Android 手机重启解决方案
- GNS3 安装图解 简单易学 多操作几遍就能记住
- 去除图片水印的快速方法,操作简单看完就会!