【数据库】MySQL的MVCC(Multi-Version Concurrency Control)多版本并发控制

MySQL的MVCC(Multi-Version Concurrency Control)多版本并发控制

一、前言

1、MySQL为了保证事务的隔离性,实现数据库的隔离级别,引入了MVCC
2、需要了解undo log入门
3、需要了解快照ReadView入门
4、先看下面的MySQL的快照读、当前读。

快照读:
读取的是记录的可见版本 (有可能是历史版本),不用加锁。简单纯粹的查询操作,属于快照读。
如:

SELECT * FROM student WHERE id=1;

当前读:
读取的是记录的最新版本,并且当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。特殊的查询操作、插入、更新、删除操作,属于当前读。
如:

SELECT * FROM student WHERE id=1 LOCK IN SHARE MODE; //共享锁(S)
SELECT * FROM student WHERE id=1 FOR UPDATE; //排他锁(X)
INSERT INTO student VALUES (1, '张三'); //排他锁(X)
UPDATE student SET name='李四' WHERE id=1; //排他锁(X)
DELETE FROM student WHERE id=1; //排他锁(X)

插入、更新、删除都属于当前读,因为这三个操作内部就包含了一个当前读。(插入操作可能会触发Unique Key的冲突检查)
如update操作的具体流程:

  1. 开始执行update的sql,MySQL Server会根据where条件,读取第一条满足条件的记录,然后InnoDB引擎会将第一条记录返回,并加锁。
  2. 等待MySQL Server收到这条加锁的记录之后,会再发起一个update请求,更新这条记录。
  3. 一条记录操作完成,再读取下一条记录,直到没有满足where的条件为止。
二、MySQL里MVCC的实现

一般MVCC有2种实现方法:

  1. 写新数据时,旧数据不删除,而是把新数据插入。PostgreSQL就是使用的这种实现方法。
  2. 写新数据时,把旧数据转移到一个单独的地方,如回滚段中,其他人读数据时,从回滚段中把旧的数据读出来,如Oracle数据库和MySQL中的innodb引擎。

简单来说,MySQL的MVCC给我们提供了读取当前数据库中行数据的一种方式,如果读取的行正在执行DELETE或UPDATE操作,读取操作不会因此去等待上锁的行释放,而是去读取行的一个快照。
如图:
在这里插入图片描述

上图直观地展现了InnoDB一致性非锁定读的机制。之所以称其为非锁定读,是因为不需要等待行上排他锁的释放。快照数据是指该行的之前版本的数据,每行记录可能有多个版本,一般称这种技术为行多版本技术。由此带来的并发控制,称之为多版本并发控制(Multi Version Concurrency Control / MVCC)。InnoDB是通过undo log来实现MVCC。

在事务隔离级别RC和RR下,InnoDB默认使用MVCC方式的一致性非锁定读。

  • 在RC下,一致性非锁定读总是读取被锁定行的最新一份快照数据。
  • 在RR下,读取事务开始时的行数据版本。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值