InnoDB并发控制系统的实现MVCC

121 阅读3分钟
  1. what

MVCC multi-version concurrent control是用于实现事务隔离同时提高并发的关键技术,允许事务同时访问同一数据而不冲突,通过为数据对象创建多个版本实现。

  1. 工作原理

原理是允许事务读取事务的某一个版本,而不是最新版本,来避免读写冲突。

当数据被更新时,不直接覆盖旧数据,而是创建一个新版本。这样子不同的事务可以看到同一数据的不同版本,从而实现并发控制。

  1. 事务ID

事务为每一个事务分配一个唯一的事务 ID ,用于记录事务的开始时间,反应事务间的执行顺序,帮助判断数据版本的可见性

  1. 数据版本控制

当事务更新数据时,不直接覆盖旧数据,而是创建一个新版本。这样子不同的事务可以看到同一数据的不同版本,从而实现并发控制。

每条记录会多两个字段

  1. 事物id(trx_id)
  2. 回滚指针(roll_pointer)

通过对比trx_id在[m_up_limit_id , m_low_limit_id] 区间的左边、中间还是右边,用来决定记录是否可见

  1. 快照读

当事务读取数据时,会根据当前事务 ID 来获取快找数据,即事务只能看到在它开始前已提交的数据,不能看到在它之后开始的事务数据

  1. Read-view

class Readviewbool changes_visible(trx id_t id, const table_name_t& name) const MY_ATTRIBUTE((warn_unused result))
    {...}
    //元组的可见性判断。重要函数,详细内容参见12.2节

   trx_id_t m_low_limit_id;
   //一个快照,有左右边界,左边界是最小值,右边界是最大值。此变量是右边界
   
   
   trx_id_t m_up_limit_id;
   //左边界,小于此值,表示发生得更早
   
   trx_id_t m_creator_trx_id;
   // 当前创建事务的事务id
   
   ids_t m_ids;
   //快照创建时,处于活动尚未完成的读写事务的集合
 
 }
  1. m_up_limit_id

快照左边界,是创建快照时,未提交的最小事务 id, target_id < 左边界,都可见

  1. m_low_limit_id

快照右边界,创建快照时,最大事务 ID+1, target_id > 有边界,不可见

  1. m_creator_trx_id

当前事务 id

  1. m_ids

创建快照时,活动的但未提交的事务 id 集合,这个集合用于可见性判断,特别在于 RC 隔离级别下,这个集合会根据新的事务开始或者现有事务结束而变化。

  1. 可见性规则

  1. 确认隔离级别

  • 读未提交(Read Uncommitted):事务可以看到其他事务未提交的更改。

  • 读提交(Read Committed):事务只能看到其他事务已提交的更改。

  • 可重复读(Repeatable Read):事务看到的是它开始时数据库的快照,不会看到其他事务在其执行期间所做的更改。

  • 可串行化(Serializable):尝试强制事务序列化执行。

  1. 流程

  1. 如果是 RU,可见

因为有了事务,说明事务开始了,就可以读未提交

  1. target_id < min_id 可见

可见,在事务之前发生且提交

  1. target_id在活跃列表中 不可见

不可见

  1. max < target_id 不可见

不可见,在事务之后发生

  1. min < target_id < max 可见

说明已经提交了

参考

cloud.tencent.com/developer/a…

《数据库事务处理的艺术:事务管理与并发控制》