mysql mvcc实现原理

innodb mvcc多版本并发控制 主要根据版本链和read view实现。

版本链说明

数据每操作一次都会在undo log中增加一条记录,每一条记录都有两个隐藏的列,trx_id(当前事务id),roll_pointer(回滚指针,指向上一次事务id) insert 回滚指针为null,举例如下。

insert into table(1,'zhang'),会在undo log增加一条记录

update table set name = 'li' where id = 1,会在undo log里增加一条记录

roll_pointer回滚指针指向了 insert产生的记录。

read view说明

read view有四个关键属性

  • m_ids :   当前活跃事务列表
  • min_trx_id: 当前m_ids中最小的事务id
  • max_trx_id:  read view产生时,系统应该分配给下一个事务的id(=creator_trx_id+1 是否正确疑问)
  • creator_trx_id: read view生成时所在事务的id。

具体取哪一个版本的数据记录,取决于当前最新记录的事务id以及read view所在的事务id,以下用data_trx_id表示当前最新纪录的事务id

1 如果data_trx_id

2 如果data_trx_id>=max_trx_id,说明该记录产生的事务是在read view之后产生的,所以对当前事务是不可见的,要根据版本链向上找寻对于当前事务可见的版本记录。

3 如果min_trx_id<=data_trx_id

  • 如果等于creator_trx_id(即当前事务id),说明该记录就是当前事务产生的可见。
  • 如果在并且不等于creator_trx_id(即当前事务id),说明事务还没提交,对于当前事务不可见,要根据版本链向上找寻对于当前事务可见的版本记录
  • 如果不存在,说明事务已经提交,对于当前事务是可见的。

举例说明m_ids为[20,30,39],min_trx_id为20,max_trx_id为40。

  1. data_trx_id为10,10小于min_trx_id,对于当前事务肯定是可见的。
  2. data_trx_id为50,50大于max_trx_id,说明read view产生时data_trx_id还未产生,当然是不可见的。
  3. data_trx_id为20,20在m_ids说明事务还未提交,不可见。
  4. data_trx_id为31,31不在m_ids中,说明事务已经提交,可见。
  5. data_trx_id为39,说明就是当前事务修改的,可见。

不同隔离级别read view创建时机不同

  • 读已提交,每次select都会产生。
  • 可重复读,只有在第一次select的时候产生,之后都是用这一份。

你可能感兴趣的:(mysql,mysql)