MVCC是什么
MVCC(Multiversion concurrency control )是同一行数据保留多版本的一种方式,进而实现并发控制。 在查询时,通过read view 和版本链 找到对应版本的数据。
MVCC的作用
提升并发性能。对于高并发场景,MVCC比行级锁开销更小
MVCC的实现原理
MVCC的实现依赖于版本链,版本链通过表的三个隐藏字段实现:
DB_TRX_ID :当前事务id(唯一)DB_ROLL_PRT :回滚指针,指向当前行记录的上一个版本DB_ROW_ID :主键,如果数据表没有主键,InnoDB会自动生成主键
表的某一行记录示例
它表示id =1,name =张三,age =19的这条行记录是由事务id =10的事务创建/修改
Read View是什么
read view 可以理解为将数据在每个时刻的状态拍成“照片”记录下来。当需要获取时刻t的数据时,就从t时间拍的”照片“上获取数据。 Read View 结构:
Read View如何判断某个版本可以访问
trx_id == creator_trx_id :修改这条行记录的事务如果和创建Read View(也就是查询这条行记录)的事务是同一个事务,那么就可以访问这个版本的行记录数据。trx_id < min_trx_id :行记录的事务id 比未提交的最小事务id 还要小。说明修改该行记录的事务已经提交。该版本的事务可以被当前事务读取到。trx_id > max_trx_id :说明当前版本的事务是在生成Read View 之后才产生,当前事务无法访问。min_trx_id <= trx_id <= max_trx_id :
- 如果在
m_ids 中存在trx_id ,说明是未提交的事务,不可访问 - 不存在,说明
trx_id 已经提交了,可以访问。
例如: 有如下两个事务 事务id =20的事务将id =1的行记录的name 先改成李四,然后改成王五。 事务id =60的事务对其他表进行一些操作。
此时进行查询select * from users where id = 1 ,生成的Read View 如下图: 此时未提交的事务有20 和60 ,所以m_ids为[20,60] 生成该Read View 的是查询语句,所以creator_trx_id =0(一个事务只有对数据库的数据进行修改操作(增,删,改)的时候,才会为事务分配一个唯一事务id,查询操作的事务没有进行对数据进行修改操作,所以trx_id就是默认的0)
将行记录的每个版本的trx_id与时间轴对比,判断此版本是否可以访问
此时查询能查询到的数据应该是name=“张三”,原因如下表:
name | trx_id == creator_trx_id | trx_id < min_trx_id | trx_id > max_trx_id | min_trx_id <= trx_id <= max_trx_id | 结果 |
---|
王五 | | | | 符合,但在m_ids中 | 无法访问 | 李四 | | | | 同上 | 无法访问 | 张三 | | 符合 | | | 可以访问 |
|