[转]关于mysql多版本并发控制

↘锁芯ラ 提交于 2020-12-15 09:44:24

多版本并发控制(MVCC)

MVCC 的思路是这样:我们为每一个事务都分配连续递增的ID(XID),同时每次更新一行数据的时候,为这一行生成一个新版本,并在新版本上记录执行这次修改事务的XID。同时全局维护一个当前未提交的事务 XID 列表(后续简称 xid_set)。

 

 

当我们要读数据的时候,首先记录当前最大的事务ID是多少(后续简称 next_xid),比这个值更大的事务在我们读数据时都还没开始执行,所以当读到数据版本XID比 next_xid 大的时候,说明当前版本在本次查询中不应该被读到,需要找这一行数据更早的版本了。但并不是 XID 比 next_xid 小的版本就一定都可以被读到,因为可能之前的一些事务还没有提交。所以在开始读数据时,除了记录 next_xid,还需要记录此时全局未提交的事务 XID 列表(就是复制一份这一时刻的 xid_set)。当读到的版本 XID 小于 next_xid 且不在 xid_set 中,这个数据就是当前应该被读取到的版本了。

所以读操作应当看见哪些版本,受这两个值的影响:

  1. 开始读操作时的最大的事务ID next_xid
  2. 开始读操作时未提交的事务ID列表 xid_set

 

这两个值唯一确定了一份数据快照(ReadView),限制了当前读事务一定只能读到已提交的数据版本,无法读到执行到一半还未提交的事务产生的变更。当写事务提交时,只需将自己的XID从全局未提交的事务列表中删除,即可让只有的读操作看到自己的变更。MVCC就是用这种方式来实现原子性的,这种方式实现原子性几乎不需要锁。

MVCC的具体实现有以下两种:

  1. 直接保存数据的所有历史版本
  2. 记录数据的最新值和undo log,通过 undo log 来恢复数据的历史版本

在 MySQL 中使用的是第二种。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!