其他分享
首页 > 其他分享> > (十二)MVCC

(十二)MVCC

作者:互联网

MVCC:多版本并发控制技术。保存数据的历史版本。这样我们就可以通过比较版本号决定数据是否显示出来。

InnoDB中的RC和RR隔离事务是基于多版本并发控制(MVCC)实现高性能事务。一旦数据被加上排他锁,其他事务将无法加入共享锁,且处于阻塞等待状态,如果一张表有大量的请求,这样的性能将是无法支持的;MVCC对普通的 Select 不加锁,如果读取的数据正在执行Delete或Update操作,这时读取操作不会等待排它锁的释放,而是直接利用MVCC读取该行的数据快照。

事务版本号

每开启一个事务,我们都会从数据库中获得一个事务ID(也就是事务版本号),这个事务ID是自增长的,通过ID大小,我们就可以判断事务的时间顺序。

InnoDB的叶子节点存储的内容

Undo log

InnoDB将行数据快照保存在了Undo Log里。回滚指针将数据行的所有快照记录都通过链表的结构串联了起来,每个快照的记录都保存了当时的trx_id,也是那个时间点操作这个数据的事务ID。这样如果我们想要找历史快照,就可以通过遍历回滚指针的方式进行查找。

Read View

read view可以解决行的可见性。Read View是一个数组,由小到大保存了当前事务开启时所有还没有提交的事务列表,即不应该让这个事务看到的其他的事务ID列表。

当前有事务creator_trx_id想要读取某个行记录,这个行记录在叶子节点中的事务ID为trx_id,那么会出现以下几种情况:

MVCC下查询一条记录:

InnoDB中,MVCC是通过Undo Log + Read View进行数据读取,Undo Log保存了历史快照,而Read View规则帮我们判断当前版本的数据是否可见。

  1. 首先获取事务自己的版本号,也就是事务ID;
  2. 获取当前事务的Read View;
  3. 查询行数据的事务id,然后与Read View中的事务版本号进行比较;
  4. 如果不符合ReadView规则,就需要从Undo Log中获取历史快照;
  5. 最后返回符合规则的数据。

读已提交实现机制:

在隔离级别为读已提交(Read Commit)时,一个事务中的每一次SELECT查询都会获取一次Read View,同样的查询语句都会重新获取一次Read View,这时如果Read View不同,就可能产生不可重复读或者幻读的情况。

可重复读实现机制:

当隔离级别为可重复读的时候,事务只在第一次SELECT的时候会获取一次Read View,而后面所有的SELECT都会复用这个Read View,这样就能同一事务读取数据不一致的情况。

InnoDB三种行锁的方式:

InnoDB幻读解决机制:

InnoDB可以通过Next-Key锁+MVCC来解决幻读问题。InnoDB事务中,通过Next-Key锁住事务读取的范围,解决幻读情况。

例如:事务的读取height> 2.08 , Next-key将锁住heiht>2.08的部分,这样其他事务想要插入时就会失败,解决幻读问题。

标签:事务,Read,十二,ID,trx,MVCC,id,View
来源: https://www.cnblogs.com/greengages/p/16620924.html