【MySQL基础】MVCC多版本并发控制

MVCC - 多版本并发控制

MVCC,全称 Multi-Version Concurrency Control,即多版本并发控制。通过维持一个数据的多个版本,来控制并发。

一、MVCC 概述

1、三种并发场景

  • 读-读:不存在任何问题,也不需要并发控制。
  • 读-写:有并发问题,可能会造成事务隔离性问题,可能遇到脏读幻读不可重复读
  • 写-写:有并发问题,可能会存在更新丢失更新覆盖的问题。

2、当前读 & 快照读

  • 当前读

    读取的是记录的最新版本,读取时要加锁,保证其他并发事务不能修改当前记录。(如共享锁和排他锁)

  • 快照读

    读取的可能是记录的历史版本,读取时不加锁

注意:快照读在MySQL的串行隔离级别下会上升为当前读,即使是select操作也会加锁。

3、MVCC的作用

MVCC就是为了不采用悲观锁这样性能不佳的形式去解决读-写的并发问题,而提出的解决方案。

  • 可以做到读操作不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能(解决了读-写并发问题)
  • 可以解决脏读幻读不可重复读等事务隔离问题,但不能解决更新丢失的问题(仍存在写-写并发问题)

4、结合MVCC处理并发问题

因为有了MVCC,所以我们可以形成两个组合:

  • MVCC + 悲观锁:MVCC解决读-写的并发问题,悲观锁解决写-写的并发问题

  • MVCC + 乐观锁:MVCC解决读-写的并发问题,乐观锁解决写-写的并发问题

这种组合的方式,可以最大程度的提高数据库并发性能,并解决数据库的并发问题。

二、MVCC 实现原理

MVCC 在 MySQL 中的具体实现是由 隐式字段 + Undo Log + Read View 完成的。

1、隐式字段

数据库中的每行记录,除了我们自定义的字段外,还有数据库隐式定义的一些字段:

名称 字段 占用 作用
隐式主键 DB_ROW_ID 6 byte 如果数据表没有主键,InnoDB会自动根据 DB_ROW_ID 产生一个聚簇索引。
事务ID DB_TRX_ID 6 byte 记录 创建这条记录最后一次修改这条记录 的事务ID(即最新的事务ID)
回滚指针 DB_ROLL_PTR 7 byte 指向这条记录的上一个版本(存储于rollback segment里)

2、回滚日志 Undo Log

MVCC 使用到的快照存储在 undo log 中,该日志通过回滚指针把一个数据行(Record)的所有快照连接起来。

在这里插入图片描述

如何获取一条记录的历史版本呢?

在这里插入图片描述

虚线框里是同一行数据的4个版本,图中的三个虚线箭头U1、U2、U3就是undo log。

  • V1、V2、V3并不是物理上真实存在的,而是每次需要的时候,根据 当前版本V4undo log 计算出来的。

3、一致性视图 Read View

上一节说到,多个事务对同一行记录进行更新会产生多个历史版本,这些历史版本可以通过 当前版本undo log 计算出来。

但是,如果一个事务要想查询某条行记录,需要读取哪个版本的行记录呢?这时就需要根据 Read View 来进行判断了。

1)什么时候生成?

不同的隔离级别下,生成Read View的时机也是不一样的(MVCC主要解决 RC 和 RR 两种隔离级别)

  • 可重复读(RR):当前事务第一次select时,创建Read View,之后事务里的其他查询都共用这个Read View。
  • 读已提交(RC):每一个select执行之前,都会重新创建一个新的Read View。

2)可见性判断

如何通过 Read View 判断当前事务能够看到哪个版本的数据呢?

  1. 获取行记录的最新事务ID(即DB_TRX_ID
  2. 根据 Read View 的 可见性算法 判断可见性。
  3. 若不符合可见性,就通过 回滚指针 取出 上一版本的事务ID 再进行判断
    • 遍历版本链的 事务ID(从链首到链尾,从最新的版本开始判断),直到找到符合可见性的 事务ID
  4. 符合可见性的事务ID所在的版本,就是当前事务能看见的最新版本。

3)可见性算法(属性)

// MySQL源码分析
class ReadView {
   
   
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scj1022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值