Day57 【概念解析】 MVCC
目录 ▼
前言
😄 通过介绍MVCC的定义、特性以及在InnoDB中的实现来获取高并发。
整理定义
MVCC(multiversion concurrency control),多版本并发控制。
Multiversion concurrency control (MCC or MVCC), is a concurrency control method commonly used by database management systems to provide concurrent access to the database and in programming languages to implement transactional memory.
多版本并发控制(MCC或MVCC)是数据库管理系统常用的一种并发控制方法,用于提供对数据库的并发访问,并在编程语言中实现事务性内存。
复述展开
Why MVCC?
InnoDB通过使用MVCC来获取高并发性,并且实现了SQL标准的4种隔离级别,其中,在InnoDB中,默认级别为 REPEATABLE-READ(可重复读)。值得一提的是,InnoDB使用了 next-key lockling(临键锁) 的策略来避免幻读(phantom)现象的产生。
之前在数据库事务这一概念中,介绍了SQL标准的4种隔离级别
SQL标准的4种隔离级别
MySQL :: MySQL 8.0 Reference Manual :: 15.7.2.1 Transaction Isolation Levels
What is MVCC
MVCC 多版本并发控制
😄 MySQL的大多数事务型存储引擎实现都不是简单的行级锁。基于提升并发性考虑,一般都同时实现了多版本并发控制(MVCC),包括Oracle、PostgreSQL。只是实现机制各不相同。
MVCC 的实现是通过保存数据在某个时间点的快照来实现的。也就是说不管需要执行多长时间,每个事物看到的数据都是一致的。
典型的MVCC实现方式,分为乐观(optimistic)并发控制和悲观(pressimistic)并发控制。下边通过 InnoDB的简化版行为来说明 MVCC 是如何工作的。
InnoDB 的 MVCC,是通过在每行记录后面保存两个隐藏的列来实现。这两个列,一个保存了行的创建时间,一个保存行的过期时间(删除时间)。
当然存储的并不是真实的时间,而是系统版本号(system version number)。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
💡 隐藏字段说明
REPEATABLE READ(可重读)隔离级别下MVCC如何工作:
-
SELECT:InnoDB会根据以下两个条件检查每行记录:
-
InnoDB只查找版本早于当前事务版本的数据行,这样可以确保事务读取的行,要么是在开始事务之前已经存在要么是事务自身插入或者修改过的
-
行的删除版本号要么未定义,要么大于当前事务版本号,这样可以确保事务读取到的行在事务开始之前未被删除
-
只有符合上述两个条件的才会被查询出来
-
INSERT:InnoDB为新插入的每一行保存当前系统版本号作为行版本号
-
DELETE:InnoDB为删除的每一行保存当前系统版本号作为行删除标识
-
UPDATE:InnoDB为插入的一行新纪录保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为删除标识
保存这两个额外系统版本号,使大多数操作都不用加锁。使数据操作简单,性能很好,并且也能保证只会读取到符合要求的行。不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作和一些额外的维护工作。
MVCC 只在 COMMITTED READ(读提交)和REPEATABLE READ(可重复读)两种隔离级别下工作。
💡 多版本与二级索引
理解体会
多版本控制(Multiversion Concurrency Control): 指的是一种提高并发的技术。最早的数据库系统,只有读读之间可以并发,读写,写读,写写都要阻塞。引入多版本之后,只有写写之间相互阻塞,其他三种操作都可以并行,这样大幅度提高了InnoDB的并发度。在内部实现中,InnoDB通过undo log保存每条数据的多个版本,并且能够找回数据历史版本提供给用户读,每个事务读到的数据版本可能是不一样的。在同一个事务中,用户只能看到该事务创建快照之前已经提交的修改和该事务本身做的修改。
理解InnoDB中的MVCC非常关键,了解引入的背景已经如何实现的原理。
参考
MySQL :: MySQL 8.0 Reference Manual :: 15.3 InnoDB Multi-Versioning