论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
软件与程序人生
›
后端开发
›
.Net
›
MVCC多版本并发控制的理解
MVCC多版本并发控制的理解
麻花痒
金牌会员
|
2022-9-6 08:13:52
|
显示全部楼层
|
阅读模式
楼主
主题
916
|
帖子
916
|
积分
2748
前置知识
当前读与快照读
当前读
什么是当前读:读取的是最新的数据,不会读到老数据。
何时触发:update、insert、delete、select lock in share mode、select for update时,总是当前读。
快照读
什么是快照读:读取的是历史版本,不是最新的数据。
何时触发:select
这些关系一定要搞清楚!
事务的ACID
原子性:事务要么全部成功,要么全部失败。实现:undolog回滚日志实现。相当于存储在磁盘中的历史记录链、还有一个更官方的名字:快照。
一致性:由另外三个共同达到一致性。
隔离性:事务并发执行时内部操作不能互相干扰。实现:锁实现。
持久性:事务一旦提交,对数据库的影响应该是永久的。实现:redolog实现。
Innodb引擎的日志
1、undolog
作用:
保存历史快照。
目的:
实现原子性,在MVCC中也起到了一定的作用。
2、redolog
作用:
预写日志。
目的:
为了高效实现持久性,将数据持久化。
详解:
首先,在执行数据更新时,效率是低的,目前几乎所有软件硬件的瓶颈,都卡在了IO层面。IO有两种:顺序读写、随机读写。那明明是解释redolog的,怎么就说起了IO呢?这要先明确一点,就是顺序读写与随机读写的效率是谁快谁慢的问题。顺序读写:顾名思义,就是顺序向尾部一次添加数据,属于append的操作,不需要查找。随机读写:需要指针的移动查找。所以很明显,顺序读写的效率是要远高于随机读写的。举个例子,比如在一家饭店,中午有人来吃饭,这家店允许赊账,所以很多人会选择赊账,而店主呢,就把所有的赊账信息记录在一本厚厚的本子里,假设里面记了一万条赊账信息。好了,中午最繁忙的时候,所有员工都在忙着工作,如果有人要赊账,怎么办?根本没机会一个一个仔细找记录。所以很自然的就会想到,我在墙上装个黑板,或者单独在一张纸上列出来今天的赊账名单。等不忙了,我再慢慢地把名单记录到本子里。所以,现在已经很明显了,redolog就是顺序读写,它快速记录数据,然后数据再由顺序读写区域慢慢向随机读写区域转换。这就是WAL:预写日志。
redolog是Innodb引擎的日志,而MySQLserver中自带的日志中有binlog,所以它俩是共存的,所以在运行时,必须保证一致性,因为binlog是MySQL主从复制时向从机同步信息的,如果不写binlog,那么从机会出问题,但是应该先写哪一个呢?先写哪个都会出问题!一旦写第一个时断电,就会造成主机与从机不一致。解决的方法是给redolog加个状态,当redolog写完数据后,给它状态为prepare,然后去写binlog,当binlog写完后,再把redolog的状态从prepare改为commit。这就是两阶段提交。
MVCC
宏观来看,MVCC就是解决事务的隔离性的问题的。
MySQL的并发场景
MySQL的并发场景有三种:读读、读写、写写。
读读:不存在数据安全问题。
读写:存在数据安全问题。如脏读、不可重复读、幻读。
写写:存在数据安全问题。如丢失更新。
而MVCC则是以不加锁的方式解决读写冲突问题。
MVCC的组成部分
表的隐藏字段:数据库表在定义时除了自己声明的字段,还会包括一些隐藏字段,包括有:
DB_TRX_ID :最近修改事务ID。指创建这条记录或最后一次修改这条记录的事务id。
DB_ROLL_PTR :回滚指针。指向记录的上一个版本,即指向undolog首条记录。
DB_ROW_ID :隐藏主键。如果表没有主键,自动生成一个6字节的row id。
readview
快照读时会产生readview,即select时会产生readview。
举个demo:
当select时,产生了快照读,此时生成的readview可以看到。
而如何看能否读取到值呢?MySQL有可见性算法。
再举一个demo
对比一下,如果按照我们的判断,可以发现蓝色的readview与第一个demo中的readview一模一样。但是问题在于,蓝色的select是不能读取到修改之后的数据的。这当然是因为蓝色的readview是错误的,它真正的readview其实就是黄色的readview,也就是下图
结论
所以,隔离级别解决数据不可重复读的关键,在于MVCC生成readview的机制或者时机,如果是读已提交级别RC,每次快照读都会生成readview,所以会产生不可重复读的问题。如果是可重复读隔离级别RR,只会在第一次快照读时产生readview,不会有不可重复读的问题。
至此,MVCC结束
至于幻读问题,则需要加锁来解决,幻读产生的根本原因在于:当前读和快照读一起使用!如果一个事务中只有快照读,那么永远不会出现幻读问题。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
麻花痒
金牌会员
这个人很懒什么都没写!
楼主热帖
【SQL server速成之路】——身份验证及 ...
容器开发运维人员的 Linux 操作机配置 ...
2022年安装Kali Linux最详细过程,以及 ...
我今年12岁了,我喜欢打游戏,怎么能成 ...
猜
密码学奇妙之旅、02 混合加密系统、AES ...
窄带传输与LoRa扩频传输技术应用方案对 ...
kubectl使用技巧:如何更方便地操作多 ...
程序员坐牢了,会被安排去写代码吗? ...
Redis哨兵
标签云
存储
服务器
快速回复
返回顶部
返回列表