高性能MySQL(第3版)笔记 1.4多版本并发控制

MVCC

全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。
可以认为MVCC是行级锁的一个变种,但是它在很多种情况下避免了加锁操作,因此开销更低。其他数据库(Oracle、PostgreSQL)等也都实现了MVCC,他们的实现机制不尽相同,因为MVCC没有一个统一的实现标准。虽然实现机制有所不同,但大都实现了非阻塞读操作,写操作也只锁定必要的行。

实现原理

MVCC的实现,是通过保存数据在某个时间点的快照实现的,也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。

不同存储引擎的MVCC实现是不同的,典型的有乐观(optimistic)并发控制和悲观(pessimistic)并发控制。
InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。存储的时间其实是系统版本号(system version number)。每开始一个新的事务,系统版本号都会递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。下面看一下Repeatable Read(可重复读)隔离级别下,存储引擎是InnoDB的MVCC具体是如何操作的。

操作类型 操作
SELECT a. 只查找版本早于或等于当前事务版本的数据行,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。b. 行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。只有复合上述两个条件的记录,才能作为返回结果
INSERT 为新插入的每一行保存当前系统版本号作为行版本号。
DELETE 为删除的每一行保存当前系统版本号作为行删除标识
UPDATE 为插入新一行记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识

保存这两个额外的系统版本号,使大多数读操作都可以不用加锁。不过不足之处自然是每行记录都需要额外的存储空间,需要更多的行检查工作,以及一些额外的维护工作。

生效的隔离级别

MVCC只在Repeatable Read和Read Committed两个隔离级别下工作,Read Uncommitted总是读取最新的数据行,而不是复合当前事务版本的数据行。而Serializable则会对所有读取的行都加锁。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章