这个机制确实不清楚,百度查了以后,记录下来:
MVCC
Multi-Version Concurrency Control 多版本并发控制,MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问;在编程语言中实现事务内存。
可将MVCC 看成行级别锁的一种妥协,在许多情况下避免使用锁,同时可以提供更小的开销。根据实现的不同,它可以允许非阻塞式读,在写操作进行时只锁定必要的记录。在一般情况下,事务性存储引擎不只是只使用表锁,行加锁的处理数据,而是同时结合了MVCC机制,以处理更多的并发问题。
MVCC会保存某个时间点的数据快照。意味着事务可以看到一个一致性的数据视图。各个存储引擎对于MVCC的实现各不相同。这些不同中的一些包括乐观和悲观的InnoDB 版本的行为展示MVCC工作的一个侧面。
那么MySQL到底是怎么实现MVCC的?
在MySQL 中MVCC是在InnoDB存储引擎中得到支持的,是通过每行记录后面保存两个隐藏的列来实现的,分别是:一个保存了这个行的创建时间,另一个保存的是行的删除时间。这个存储的并不是实际的时间值,而是系统版本号(可以理解为事物的ID),每开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号作为事务的ID。
insert语句后其实对应在数据中的表如下(后面两列是隐藏列,我们通过查询语句看不到)
id | name | 创建时间(事务ID) | 删除时间(事务ID) |
1 | a | 1 | undefined |
2 | b | 1 | undefined |
3 | c | 1 | undefined |
SELECT
InnoDB 会根据以下两个条件检查每行记录:
a.InnoDB 会查找版本早于当前事务版本号小于或者等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始之前已经存在的,要么是事务自身插入或者修改过的,
b.行的删除版本(时间)要么未定义,要么大于当前事务版本号,这可以确保事务读取到的行,在事务开始之前未被删除。
只有a,b同时满足的记录,才能返回作为查询结果
DELETE
InnoDB 会作为删除的每一行保存当前系统的版本号(事务ID)作为删除标识,即更改删除时间字段
Update
InnoDB 执行UPDATE,实际上是插入了一行记录,并保存其创建时间为当前事务的ID,同时保存当前事务ID到要UPDATE 的行删除时间。
总而言之:Mysql 是通过为每一行记录保存两个隐藏的字段 '创建时间(事务ID)',’删除时间(事务ID)',通过每个事务执行的操作,对应的对这两个字段进行更新,同时,在select时只能查询创建时间小于当前的且删除时间大于当前时间的记录,delete 只能删除删除时间大于当前时间的。这里的时间都是事务的版本号。