InnoDB MVCC原理

MySQL系列

第一章:sql_mode模式
第二章:optimize table、analyze table、alter table、gh-ost
第三章:InnoDB MVCC原理


一、隔离性与隔离级别

在平时的开发工作中,经常使用MySQL InnoDB的事务特性ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性),隔离性性就是其中的I。当多个事务同时执行的时候,就会出现脏读、不可重复读、幻读问题。而隔离性就是为了解决这些问题。当然任何技术都是没有银弹的,都正反两个方面,隔离性也不例外,隔离性越高,并发能力越低。
InnoDB目前支持DB标准中的四个隔离级别,如下所示:

  • 读未提交(read uncommited)
    一个事务还没有提交,它的变更可以被其他事务查看到。
  • 读提交(read committed)
    事务提交后,它的变更后才能被其他事务查看到。
  • 可重复读(repeatable read)
    事务执行过程中,看到的数据和事务启动时看到的事务保持一致,也就是说该事务执行过程中的事务变更的数据不可见。
  • 串行化(serializable )
    数据的读锁,写锁,会出现冲突,必须等到前一个锁执行完才能执行。我们熟知的Redis就是使用单线程来执行命令,也就是串行化保证数据的隔离性。

二、MVCC原理

MVCC主要用在读提交、可重复读中,而MySQL的默认隔离级别就是可重复读。MVCC原理使用行记录的隐藏队列,先熟悉一下:

1.行记录隐藏列

  • row_id
    行ID,6字节,记录的唯一标识;当用户在表中定义了主键字段就优先选择用户定义的主键,如果没有,就查找是否有定义不为null的唯一索引,如果有就把该列作为主键,如果没有MySQL就会生成一列row_id隐藏列作为主键。
  • trx_id
    当前记录项的事务id,6字节,每开始一个新的事务时,系统版本号会自动递增,而事务开始时刻的系统版本号会作为事务id,事务 commit 的话,就会更新trx_id。
  • roll_pointer
    undo log 指针,7字节,指向当前记录项的 undo log,找之前版本的数据需通过此指针。如果事务回滚的话,则从 undo Log 中把原始值读取出来再放到记录中去。

2.MVCC 原理

基于行记录中隐藏的列,实际上每行记录,可能会有多个版本的数据。当一个事务启动时,会先向MySQL申请一个事务ID(按照申请顺序严格递增的)。在本事务ID之前已经提交的事务,本事务可见,否则,就要根据行数据的roll_pointer指针往前找,直到找到符合条件的数据版本。因此有了这个事务ID,就可以根据行数据隐藏列的trx_id,roll_pointer,找到对应可见版本的数据,也就是拥有了一个整个数据库的快照。
在实现上, InnoDB 为每个事务构造了一个数组,用来保存这个事务启动瞬间,当前正在“活跃”的所有事务 ID。“活跃”指的就是,启动了但还没提交。数组里面事务 ID 的最小值记为低水位,当前系统里面已经创建过的事务 ID 的最大值加 1 记为高水位。这个视图数组和高水位,就组成了当前事务的一致性视图(read-view)。而数据版本的可见性规则,就是基于数据的 row trx_id 和这个一致性视图的对比结果得到的。
mvcc
这样,对于当前事务的启动瞬间来说,一个数据版本的 row trx_id,有以下几种可能:

  • 如果落在绿色部分,表示这个版本是已提交的事务或者是当前事务自己生成的,这个数据是可见的
  • 如果落在红色部分,表示这个版本是由将来启动的事务生成的,是肯定不可见的;
  • 如果落在黄色部分,那就包括两种情况
    a. 若 row trx_id 在数组中,表示这个版本是由还没提交的事务生成的,不可见;
    b. 若 row trx_id 不在数组中,表示这个版本是已经提交了的事务生成的,可见。

3.当前读

当执行update、或者select加锁(select … lock in share mode、select … for update)时,事务读取数据最新的数据,叫做当前读。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值