MySQL的多版本并发控制(MVCC)

本文介绍了MVCC(多版本并发控制)在数据库中的应用,包括快照读和当前读的区别,以及InnoDB如何通过Undolog和ReadView来处理并发场景,确保数据一致性。重点讲解了隐式字段和事务日志在实现过程中的作用。
摘要由CSDN通过智能技术生成

MVCC

MVCC,是Multiversion Concurrency Control的缩写,翻译过来是多版本并发控制,和数据库锁样,他也是一种并发控制的解决方案

我们知道,在数据库中,对数据的操作主要有2种,分别是读和写,而在并发场景下,就可能出现以下 旦三种情况:读-读并发,读-写并发,写-写并发
我们都知道,在没有写的情况下读-读并发是不会出现问题的,而写-写并发这种情况比较常用的就是通过加锁的方式实现。那么,读-写并发则可以通过MVCC的机制解决

快照读和当前读

快照读:就是读取的快照数据,即快照生成的那一刻的数据,像我们常用的普通的SELECT语句在不加锁的情况下就是快照读

如:select *  from table_name  where xxx;

当前读:当前读就是读取最新数据,加锁的select,或者对数据进行增删改都会进行当前读,

如:SELECT *FROM xx_table LOCK IN SHARE MODE;

SELECT *FROM xx_table FOR UPDATE;

INSERT INTO xx_table ...;DELETE FROM xx_table ...;UPDATE xx_table ...;

在mysql中只有已提交读和重复读两种事物隔离级别才会使用快照读

不同 SQL 语句对加锁的影响,不同的 SQL 语句当然会加不同的锁,总结起来主要分为五种情况:
SELECT ... 语句正常情况下为快照读,不加锁;
SELECT ... LOCK IN SHARE MODE 语句为当前读,加 S(共享锁) 锁;
SELECT ... FOR UPDATE 语句为当前读,加 X (排它锁)锁;
常见的 DML 语句(如 INSERT、DELETE、UPDATE)为当前读,加 X(排它锁) 锁;
常见的 DDL 语句(如 ALTER、CREATE 等)加表级锁,且这些语句为隐式提交,不能回滚

SELECT *这种普通的读取操作其实也会在事务的上下文中执行,即使没有明确的开启事务语句,InnoDB存储引擎也会为查询自动开启一个隐式事务

Undolog

undo log是Mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于回退的日志,在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退。
这里面提到的存在undo log中的"更新前的数据”就是我们前面提到的快照。所以,这也是为什么很多人说UndoLog是MVCC实现的重要手段的原因。
那么,一条记录在同一时刻可能有多个事务在执行,那么,undo log会有一条记录的多个快照,那么在这一时刻发生SELECT要进行快照读的时候,要读哪个快照呢?
这就需要用到另外几个信息了

行记录的隐式字段

数据库中除了自己定义的字段外,还有一些重要的隐式字段

  • db_row_id:隐藏的行 ID,用来生成默认聚集索引。如果我们创建数据表的时候没有指定聚集索引,这时 InnoDB 就会用这个隐藏 ID 来创建聚集索引。采用聚集索引的方式可以提升数据的查找效率。
  • db_trx_id:操作这个数据的事务 ID,也就是最后一个对该数据进行插入或更新的事务 ID。
  • db_roll_ptr:回滚指针,也就是指向这个记录的 Undo Log 信息

因为每一次修改之前都会先存储一份快照到undo log中,那么这几个隐式字段一会一起保存到undo log中,就这样,每一个快照中都有一个db_trx_id 事物id字段表示了对这条记录最新一次修改的事物ID,以及一个回滚指针指向上一个快照地址

Read View

有了undo log,又有了几个隐式字段,我们好像还是不知道具体应该读取哪个快照,那怎么办呐

这就需要用到read View

read view 主要来帮我们解决可见性问题的,即他会来告诉我们应该看到哪个快照,不应该看到哪些快照

在 Read View 中有几个重要的属性:

  • trx ids,系统当前未提交的事务 ID 的列表
  • low limit id,应该分配给下一个事务的id 值
  • up limit id,未提交的事务中最小的事务 ID
  • creator trx id,创建这个 Read View 的事务ID

其实原值比较简单:那就是事物ID大的事务应该能看到事务ID小的事物的变更结果,反之则不能

所以,总结一下,

在InnoDB中,MVCC就是通过Read View + Undo Log来实现的,undo log中保存了历史快照,r而Read View用来判断具体哪一个快照是可见的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值