https://www.h5w3.com/121319.html
MVVC多版本控制
MVCC(Multi-Version Concurrency Control),行级锁的一个变种,在很多情况下避免了加锁操作,开销更低。
通过保存数据在某个时间点的快照来实现。即是不管执行多长时间,每个事务看到的数据都是一致的。
根据事务开始时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。
其实就是在高并发的访问状态下,对数据进行多版本控制,并通过事务的可见性来保证事务能看到自己应该看到的数据版本。
「那个多版本是如何生成的呢?」
每一次对数据库的修改,都会在 Undo 日志中记录当前修改记录的事务号及修改前数据状态的存储地址(即 ROLL_PTR),以便在必要的时候可以回滚到老的数据版本。
InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。两列,一个保存了行的创建时间,一个保存了行的过期时间(或删除时间),存储的并不是实际的时间值,而是系统版本号。每开始一个事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现「提交读」和「可重复读」这两种隔离级别。而未提交读隔离级别总是读取最新的数据行,无需使用 MVCC。可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。
快照读与当前读
在 MVCC 并发控制中,读操作可以分为两类: 快照读(Snapshot Read)与当前读 (Current Read)。
「快照读」:
读取的是记录的可见版本(有可能是历史版本),不用加锁。
「当前读」:
读取的是记录的最新版本,并且当前读返回的记录,都会加锁,保证其他事务不会再并发修改这条记录。
注意:MVCC 只在 Read Commited 和 Repeatable Read 两种隔离级别下工作。
「如何区分快照读和当前读呢?」
快照读:简单的 select 操作,属于快照读,不需要加锁。
当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。