前言
如何控制并发是数据库领域中非常重要的问题之一,MySQL为了解决并发带来的问题,设计了事务隔离机制、锁机制、MVCC机制等等,用一整套机制来解决并发问题,本文主要介绍MySQL5.7版本的MVCC机制。
一、MVCC 介绍
MVCC, 全称 Multi-Version Concurrency Control(多版本并发控制)
利用多版本解决的是读写并发冲突, 做到读写冲突时, 避免加锁, 实现非阻塞的读操作, 也就是无锁并发控制
.
很多数据库也都有各自的实现,像Oracle、PostgreSQL、SQLSerer、MySQL等,但没有统一的标准,所以内部实现也各有差异。
二、MySQL MVCC 介绍
MySQL的InnoDB引擎支持MVCC, 工作原理
是使用数据在某个时间点的快照来实现。这意味着,无论事务运行多长时间,都可以看到数据的一致视图,也意味着不同的事务可以在同一时间看到同一张表中的不同数据! 上文回顾:MySQL事务隔离机制 – 必须说透
为了更好的理解, 我们先了解两个重要概念:当前读和快照读
- 当前读:官方叫做 Locking Reads(锁定读取), 读取数据的最新版本. 常见的 update/insert/delete、还有 select … for update、select … lock in share mode 都是当前读.
官方文档:https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html - 快照读:官方叫做 Consistent Nonlocking Reads(一致性非锁定读取), 也就是 MVCC 生成的 ReadView, 用于普通的 select 的语句.
官方文档:https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html
这里需要多啰嗦一下consistent read
(源码里到处可见):
- 一种读取操作, 使用数据在某个时间点的快照显示查询结果, 而不考虑同时运行的其他事务所执行的更改. 如果查询的数据已被另一个事务更改, 则会根据undo log的内容重建原始数据. 该技术避免了一些锁定问题,这些问题可以通过强制事务等待其他事务完成来减少并发性.
- 对于
REPEATABLE READ
隔离级别, 快照基于执行第一次读取
操作的时间. 使用READ COMMITTED
隔离级别,快照将重置为每次一致读取
操作的时间. - 一致读取是InnoDB以READ COMMITTED和REPEATABLE READ隔离级别处理SELECT语句的
默认模式
. 由于一致读取不会对其访问的表设置任何锁,因此在对表执行一致读取时, 其他会话可以自由修改这些表.
官方文档:https://dev.mysql.com/doc/refman/5.7/en/glossary.html#gl