MVCC实现

1 介绍

MVCC(Multi Version Concurrency Control的简称),代表多版本并发控制,读不加锁,读写不冲突。在读多写少的OLTP应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能

1.1 当前读与快照读

在MVCC并发控制中,读操作可以分成两类,快照读与当前读

  • 快照读

    • 读取的是记录数据的可见版本(可能是过期的数据),不用加锁

    • 简单select使用该读取方式

  • 当前读

    • 读取的是记录数据的最新版本,并且当前读返回的记录都会加上锁,保证其他事务不会再并发的修改这条记录

    • select ... lock in share mode

    • select ... for update

    • insert

    • update

    • delete

    • 以上查询将使用当前读

1.2 使用场景

在RC和RR隔离级别下,innodb通过快照读方式读取数据时使用

2 具体实现

2.1 隐藏列

innodb行都设置了隐藏列(对查询不可见),和MVCC有关的包含如下

  • DATA_TRX_ID: 产生这条记录的事务ID,INSERT/UPDATE/DELETE时都会更新这个记录

  • DATA_ROLL_PTR: 指向该行回滚段的指针,该行上所有旧的版本,在undo中都通过链表的形式组织,该值指向undo中下一个历史记录,历史记录按照由新到旧顺序排列

  • DELETED: BIT位,删除标志0或者1

2.2 事物链表(当前活跃链表)

  • MySQL中的事务在开始到提交这段过程中,都会被保存到一个叫trx_sys的全局事务链表中,这是一个基本的链表结构

  • 事务链表中保存的都是还未提交的事务,事务一旦被提交,则会被从事务链表中摘除

2.3 ReadView

在SQL开始的时候被创建的一个数据结构,包含以下三个

  • low_limit_id 表示该SQL启动时,当前事务链表中最大的事务id编号,也就是最近创建的除自身以外最大事务编号;

  • up_limit_id 表示该SQL启动时,当前事务链表中最小的事务id编号,也就是当前系统中创建最早但还未提交的事务;

  • trx_ids 存储当前trx_sys事务链表中的事务id集合。

class ReadView {
  /* ... */
private:
  trx_id_t m_low_limit_id;      /* 大于等于view.low_limit_id的事务对于view都是不可见的 */
  trx_id_t m_up_limit_id;       /* 小于view.up_limit_id的事务对于view一定是可见的 */    
  trx_id_t m_creator_trx_id;    /* 创建该 Read View 的事务ID */  
  trx_id_t m_low_limit_no;      /* 事务Number, 小于该Number的Undo Logs均可以被Purge */
  ids_t m_ids;                  /* 创建 Read View 时的活跃事务列表 */
  m_closed;                     /* 标记 Read View 是否 close */
}

2.4 读取规则

如何判断可见性

  1. DATA_TRX_ID小于up_limit_id

    说明在事务开始前已经提交完成的数据,对于当前事务来说是可见的

  2. DATA_TRX_ID大于low_limit_id

    说明在查询的时候,这条数据还没有提交,不可见

  3. DATA_TRX_ID位于up_limit_id和low_limit_id之间

    遍历ReadView中的trx_ids,判断DATA_TRX_ID是否在其中

    如果不在,表示事务已提交,数据可见

    如果在,表示事务未提交,数据不可见

3 RC与RR快照读区别

在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。

  • RR:Read View不是事务发起时创建,而是在第一个SELECT发起后创建

  • RC:Read View不是事务发起时创建,每次SELECT发起后创建新Read View

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值