MySQL中对MVCC的理解总结
By admin
- One minute read - 80 words一、MVCC简介
MVCC (Multiversion Concurrency Control),即多版本并发控制技术。InnoDB数据库的事务隔离级别就是通过UNDO和MVCC来实现的(ACID特性),旧数据存储在UNDO中,再通过DB_ROLL_PTR 回溯查找历史版本。
二、MVCC原理
1、通过DB_ROLL_PT 回溯查找数据历史版本2、通过read view判断行记录是否可见
理解这一块之前,我们必须先了解一下row的内部存储格式
字段说明:
- DB_ROW_ID:长度6个字节。此值由InnoDB自动生成,聚集索引时使用。如果用户未显式指定表主键时,表优先使用第一个非null的唯一索引作为主键.否则使用DB_ROW_ID的值作为主键ID,聚集索引会使用此值。如果指定了表主键的话,则聚集索引使用指定的值。
- DB_TRX_ID:6个字节的事务ID。标记了最后更新此记录的事务ID,每开起一个新事务,其值自动+1
- DB_ROLL_PTR:7字节的回滚指针。指向当前记录项的undo log记录,找之前版本的数据需通过此指针。
MySQL中的MVCC原理
首次 insert
记录的DB_ROLL_PTR
指针为NULL。修改新值后,记录的 DB_ROLL_PTR
回滚指针指向原始值在Undo Log
日志的位置,也就是说将原值在Unde Log
的物理位置存储到原记录的 DB_POLL_PTR
字段。如果事务回滚的话,则从Undo Log
中把原始值读取出来再放到记录中去。如果直接commit的话,则直接保存即可。记录格式参考:
InnoDB Undo Log的日志类型 MySQL数据库InnoDB存储引擎的undo log采用了逻辑的日志。 InnoDB undo log的格式可以概括为:<操作类型>++<数据>. A. 从表中删除一行记录 TRX_UNDO_DEL_MARK_REC (将主键记入日志) 在删除一条记录时,并不是真正的将数据从数据库中删除,只是标记为已删除.这样做的好处是Undo Log中不用记录整行的信息.在undo时操作也变得很简单. B. 向表中插入一行记录 TRX_UNDO_INSERT_REC (仅将主键记入日志) TRX_UNDO_UPD_DEL_REC (将主键记入日志) 当表中有一条被标记为删除的记录和要插入的数据主键相同时, 实际的操作是更新这个被标记为删除的记录。 C. 更新表中的一条记录 TRX_UNDO_UPD_EXIST_REC (将主键和被更新了的字段内容记入日志) TRX_UNDO_DEL_MARK_REC 和 **TRX_UNDO_INSERT_REC ** 当更新主键字段时,实际执行的过程是删除旧的记录然后,再插入一条新的记录。
事务隔离级别的区别:
RR隔离级别下,在每个事务开始的时候,会将当前系统中的所有的活跃事务拷贝到一个列表中(read view)。
RC隔离级别下,在事务中的 每个语句开始(select) 时,会将当前系统中的所有的活跃事务拷贝到一个列表中(read view)
然后按照以下逻辑判断事务的可见性
MVCC解决了什么问题
MVCC使得数据库读不会对数据加锁,普通的SELECT请求不会加锁,提高了数据库的并发处理能力;
借助MVCC,数据库可以实现RC,RR等隔离级别,用户可以查看当前数据的前一个或者前几个历史版本。保证了ACID中的I特性(隔离性)。
查看当前数据库中的活跃事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX