编程知识 cdmana.com

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

一、快照读与当前读

快照读(SnapShot Read) 是一种一致性不加锁的读,是 InnoDB 并发如此之高的核心原因之一。

在 READ COMMITTED 事务隔离级别下,一致性不加锁的读是指,总是读取被锁定行的最新一份快照数据,因此其它事务修改了该行数据,该事务也能读取到,这也贴合了 RC 隔离级别下存在幻读的问题;

在 REPEATABLE READ 事务隔离级别下,一致性不加锁的读是指,事务读取到的数据,要么是事务开始前就已经存在的数据,要么是事务自身插入或者修改过的数据。(下面将以此隔离级别说明);

不加锁的简单的 SELECT 都属于快照读,例如:

SELECT * FROM t WHERE id=1;

与快照读相对应的则是当前读(Current Read),当前读就是读取最新数据,而不是历史版本的数据。加锁的 SELECT 就属于当前读,例如:

SELECT * FROM t WHERE id=1 LOCK IN SHARE MODE;SELECT * FROM t WHERE id=1 FOR UPDATE;

SELECT...FOR UPDATE 对读取的行记录加一个 X 锁,其它事务不能对已锁定的行加上任何锁。

SELECT...LOCK IN SHARE MODE 对读取的行记录加一个 S 锁,其它事务可以向被锁定的行加 S 锁,但是如果加 X 锁,则会被阻塞。

二、基于快照读的多版本并发控制

多版本并发控制技术的英文全称是:Multiversion Concurrency Control,简称 MVCC,是通过保存数据的历史版本,通过对数据行的多个版本管理来实现数据库的并发控制。这样我们就可以通过比较版本号决定数据是否显示出来,读取数据的时候不需要加锁也可以保证事务的隔离效果(可以理解成乐观锁)。

多版本并发控制(MVCC)只在可重复读(REPEATABLE READ)和提交读(READ COMMITTED)两个隔离级别下工作,其他两个隔离级别都和 MVCC 不兼容,因为未提交读(READ UNCOMMITTED),总是读取最新的数据行,而不是符合当前事务版本的数据行;而可串行化(SERIALIZABLE) 则会对所有读取的行都加锁。

MySQL 的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制(MVCC)。不仅是 MySQL,包括 Oracle、PostgreSQL 等其他数据库系统也都实现了 MVCC,但各自的实现机制不尽相同,因为 MVCC 没有一个统一的实现标准,典型的有乐观(optimistic)并发控制和悲观(pessimistic)并发控制。

三、多版本并发控制解决了哪些问题?

1. 读写之间阻塞的问题

通过 MVCC 可以让读写互相不阻塞,即读.........

版权声明
本文为[程序猿欧文]所创,转载请带上原文链接,感谢
https://my.oschina.net/mikeowen/blog/4840381

Scroll to Top