【数据库】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操作,读取操作不会因此去等待上锁的行释放,而是去读取行的一个快照。
如图:
【数据库】MySQL的MVCC(Multi-Version Concurrency Control)多版本并发控制_第1张图片

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

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

  • 在RC下,一致性非锁定读总是读取被锁定行的最新一份快照数据。
  • 在RR下,读取事务开始时的行数据版本。

你可能感兴趣的:(数据库,数据库,mysql,java,spring)