数据库实现事务隔离的方式
- 一种是在读取数据前,对其加锁,阻止其他事务对数据进行修改。
- 另一种是不用加任何锁,通过一定机制生成一个数据请求时间点的一致性数据快照(Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取。从用户的角度来看,好像是数据库可以提供同一数据的多个版本,因此,这种技术叫做数据多版本并发控制(MultiVersion Concurrency Control,简称MVCC或MCC),也经常称为多版本数据库。
InnoDB MVCC
InnoDB中的MVC是通过增加两个隐藏列来实现的。一列存储行的创建时间或修改时间,一列存储行的删除时间。时间是通过版本号(SVN)来确定的。
RepeatTable Read级别下MVCC实现
- Select
- 当前行创建列的版本号小于或等于当前事务的SVN,如果小于说明事务开始前该行已经存在,等于则说明该行被当前事务修改过
- 当前航删除列的SVN为空或大于当前事务的SVN,如果为空说明该行未被删除,大于则说明该行是在事务开始之后被删除的
- INSERT
- 修改创建列的SVN为当前事务的SVN
- DELETE
- 修改删除列的SVN为当前事务的SVN
- UPDATE
- 复制新行的创建列的SVN为当前事务的SVN,删除列的SVN为空
- 旧行的删除列为当前事务的SVN,创建列的SVN不变
MVCC相关的三个字段
- DB_TRX_ID
6BYTE,每处理一个事务,其值+1,即创建列的版本号。用1个bit标识删除操作。
- DB_ROLL_PTR
7byte,指向写到rollback segment(回滚段)的一条undo log记录(update操作的话,记录update前的ROW值)
- DB_ROW_ID
6byte,该值随新行插入单调增加,当由innodb自动产生聚集索引时,聚集索引包括这个DB_ROW_ID的值,否则聚集索引中不包括这个值