【MySQL进阶之路】实现事务隔离的方案——多版本并发控制( MVCC )和Read View理论

目录

引言

记录的隐藏列字段

undo 日志

版本链

Read View

RR 与 RC隔离级别的本质区别


个人主页:东洛的克莱斯韦克-CSDN博客

引言

多版本并发控制( MVCC )是一种用来解决 读-写冲突 的无锁并发控制 为事务分配单向增长的事务ID,为每个修改保存一个版本,版本与事务ID关联,读操作只读该事务开始 前的数据库的快照。

所以 MVCC 可以为数据库解决以下问题 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数 据库并发读写的性能 同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题

记录的隐藏列字段

字段名称大小(字节)描述
DB_TRX_ID6最近修改(修改/插入)事务ID,记录创建这条记录/最后一次修改该记录的事务ID
DB_ROLL_PTR7回滚指针,指向这条记录的上一个版本(即,指向undo log中的历史版本)
DB_ROW_ID6隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以DB_ROW_ID生成一个聚簇索引
删除标志不直接暴露隐含的字段,用于标记记录是否被删除。记录被更新或删除时,并不立即从磁盘移除,而是设置删除标志,后续由purge操作物理删除

如下实例

create table if not exists student(
name varchar(11) not null,
age int not null
);
 insert into student (name, age) values ('张三', 28);
nameageDB_TRX_IDDB_ROW_IDDB_ROLL_PTR
张三2811(如果适用,可填null或具体值)

undo 日志

在理解undo log时,我们应该将其视为一个跨越内存和磁盘的日志系统,或者简单理解成,就是 MySQL服务进程中的一段内存缓冲区,用来保存历史数据

版本链

InnoDB通过维护一个版本链来管理数据的多个版本。每条记录都包含一些隐藏字段,如db_trx_id(最后操作该记录的事务ID)和db_roll_ptr(回滚指针,指向该记录的undo日志信息)。每当事务对记录进行修改时,旧版本的数据会被保存到undo日志中,并通过db_roll_ptr连接到版本链上。

上面的一个一个版本,我们可以称之为一个一个的快照。

Read View

Read View就是事务进行 快照读 操作的时候生产的 读视图 (Read View),在该事务执行的快照读的那一 刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被 分配一个ID, 这个ID是递增的,所以最新的事务,ID值越大)

Read View 在 MySQL 源码中,就是一个类,本质是用来进行可见性判断的。 即当我们某个事务执行快照 读的时候,对该记录创建一个 Read View 读视图,把它比作条件,用来判断当前事务能够看到哪个版本的 数据,既可能是当前最新的数据,也有可能是该行记录的 undo log 里面的某个版本的数据。

Read View类的核心数据如下

m_ids:一张列表,用来维护Read View生成时刻,系统正活跃的事务ID

up_limit_id:记录m_ids列表中事务ID最小的ID(没有写错)

low_limit_id:ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的 最大值+1(也没有写错)

creator_trx_id:创建该ReadView的事务ID

Read View通过事务ID的比较,来判断哪些快照可以被该事务看到

RR 与 RC隔离级别的本质区别

正是Read View生成时机的不同,从而造成RC,RR级别下快照读的结果的不同

在RR级别下的某个事务的对某条记录的第一次快照读会创建一个快照及Read View, 将当前系统活 跃的其他事务记录起来

此后在调用快照读的时候,还是使用的是同一个Read View,所以只要当前事务在其他事务提交更 新之前使用过快照读,那么之后的快照读使用的都是同一个Read View,所以对之后的修改不可 见;

即RR级别下,快照读生成Read View时,Read View会记录此时所有其他活动事务的快照,这些事 务的修改对于当前事务都是不可见的。而早于Read View创建的事务所做的修改均是可见

而在RC级别下的,事务中,每次快照读都会新生成一个快照和Read View, 这就是我们在RC级别下 的事务中可以看到别的事务提交的更新的原因

总之在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR隔离级别下,则是 同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。

正是RC每次快照读,都会形成Read View,所以,RC才会有不可重复读问题。

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值