mysql两种实现隔离方式_【MySQL】事务的隔离级别是如何实现的

水稻: 菜瓜,听说最近你在复习MySQL方面的知识,想请教一下MySQL的事务?

菜瓜:嗯,最近刚刚看到。事务指的是MySQL中不可拆分的业务单元,具有ACID的属性。

水稻: ACID我知道啊,但是不太懂他的实现,你能说和我聊聊事务在数据库底层是怎么实现的吗?

菜瓜:据我了解,不同的特性底层的实现不一样,主要依赖两种日志和锁来实现

先说持久性:我们知道数据的操作会先在内存中完成,那么事务提交后如何保证一定能持久化到磁盘呢

redo log: 事务在提交前对数据的修改会先写到redo log 中,如果返回事务已提交成功,那么表示redo log已经记录完成。redo log 也有缓冲区,redo log的内存缓冲区大小和磁盘扇区的大小512字节一致,不会出现掉电易失的情况。另外redo log记录的是物理变化,体积很小,且redo log 写磁盘是顺序IO,极快~丝滑

redo log 和binlog区别:一个是用于做持久化,另一个用作数据恢复和复制

原子性,指的是被事务包裹的一组操作要么全部成功,要么全部失败。不会存在执行了一部分,另一部分不执行的情况

undo log: MySQL使用undo log实现操作回滚。事务开启后执行的命令都会有一条对应反向的逻辑日志计入undo日志文件中(譬如insert 就会有一条delete)。undo log的持久化会被记录在redo log中(利用redo log 速度快的特性)。一旦发生错误或者回滚的时候,利用undo就可以操作回去

水稻: 那还有一致性和隔离性呢?

菜瓜:一致性和隔离性可以放在一起说,隔离级别的选择就是一致性和隔离性的权衡

实现多个事务之间的隔离。一种是锁,另一种是mvcc机制。

水稻:锁我知道,mvcc是什么?

菜瓜:我们把数据库的读操作分为两类,一是当前读,使用锁机制;一是快照读,使用mvcc

当前读

数据的修改操作(insert update delete)和查询时显示加锁 select(查询条件后加上 lock in share mode & for update)

会锁住要读取的数据以保障数据的一致

快照读 使用的是mvcc机制,就是多版本并发控制。

除当前读之外,普通的select查询为快照读,顾名思义,就是读取的是一个快照版本,以隔离多个事务之间的数据

水稻:能不能仔细说说这个mvcc

菜瓜:可以,它的实现还是依赖undo log来做的

在RR RC两种级别下使用。其他两种不需要实现隔离

你肯定听说过mysql在RR级别下解决了幻读问题,就是依赖这个来做的

简单来说就是,MySQL维护了一个记录活跃事务id的列表readview

undo log是怎么记录的呢。举个栗子🌰

innodb的表中存在三个额外的隐藏字段,分别是编辑该条记录的事务id,更改前的undo log的回滚指针,还有一个对我们这个分析不太重要

如果有事务对该记录做了变更,事务id会更新,同时undo log里面会产生新记录,回滚指针字段指向最新的undo log链

通过比较当前事务id和readview中其他事务的id大小来决定自己读取的数据是哪个版本的undo log记录

如果当前事务id比readview中的都小,就说明该条记录没有被其他事务更改。直接读取

如果当前事务id比readview中的都大,沿着undo log链能找到最小事务id指向的undo log,该数据为稳定数据

RR级别下利用该机制避免了幻读

RC级别下每次都会读取数据的最新记录

总结:

事务的持久性和原子性由Redo log和Undo log实现

隔离性和一致性的权衡由锁机制和MVCC实现

部分内容为自己猜想,如有错误,欢迎指正!

参考文章

MySql-Undo及Redo详解 https://blog.csdn.net/aaa821/article/details/80645242

MySql MVCC 多版本并发控制 https://www.cnblogs.com/paulwang92115/p/12189487.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值