一、MVCC简介
MVCC (Multiversion Concurrency Control),即多版本并发控制技术。MVCC是通过保存数据在某个时间点的快照来实现的。不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制.
二、MVCC原理
在 MySQL 中每行row中的结构如下:
其中F1~F6表示字段信息,后面的DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR和DELETE BIT 为记录的隐藏字段,Innodb为每行记录都对其中这几个字段进行了隐藏。
这几项介绍如下:
DB_ROW_ID: 长度6个字节。此值当由InnoDB自动生成,聚集索引时使用。如果用户未显式指定表主键时,表使用DB_ROW_ID的值作为主键ID,聚集索引会使用此值。如果指定了表主键的话,则聚集索引使用指定的值。
DB_TRX_ID: 6个字节的事务ID。标记了最后更新此记录的事务ID,每开起一个新事务,其值自动+1
DB_ROLL_PTR: 7字节的 回滚指针 。指向当前记录项的undo log记录,找之前版本的数据需通过此指针。
DELETE BIT: 位用于 标识 该记录是否被删除,并不是真正的删除。
下面分别以select、delete、 insert、 update语句来说明
SELECT
Innodb检查每行数据,确保他们符合两个标准:
1、InnoDB只查找版本早于当前事务版本的数据行(也就是数据行的版本必须小于等于事务的版本),这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行。
2、行的删除操作的版本一定是未定义的或者大于当前事务的版本号,确定了当前事务开始之前,行没有被删除。
只有全部符合以上两种条件的记录才会返回。
INSERT
InnoDB为每个新增行记录当前系统版本号作为创建ID。
DELETE
InnoDB为每个删除行的记录当前系统版本号作为行的删除ID。
UPDATE
InnoDB复制了一行。这个新行的版本号使用了系统版本号。它也把系统版本号作为了删除行的版本。
说明
insert操作时 “创建时间”=DB_ROW_ID,这时,“删除时间 ”是未定义的;
update时,复制新增行的“创建时间”=DB_ROW_ID,删除时间未定义,旧数据行“创建时间”不变,删除时间=该事务的DB_ROW_ID;
delete操作,相应数据行的“创建时间”不变,删除时间=该事务的DB_ROW_ID;
select操作对两者都不修改,只读相应的数据