• MVCC(多版本并发控制)详解


    在 MySQL InnoDB存储引擎下,RC、RR 基于 MVCC 进行并发事务控制, MVCC 是基于“数据版本”对并发事务进行访问
    用一个例子来解释一下,下面是一张事务执行流程图:
    image.png
    稍微解释一下:

    1. 事务 Aid=1088 的记录的 name 改为 “张三”,并提交
    2. 事务 Bid=1088 的记录的 name 改为 “张小三”,并提交
    3. 事务 Cid=1088 的记录的 name 改为 “张老三”,并提交
    4. 事务 D 只是去查询 id=1088 的记录

    首先模拟一下在 RC 隔离级别下:事务D 第一次读取的数据是 “张三”,第二次读取的就是“张小三”
    这里应该很好理解,因为在 RC 隔离级别下,事务D 能读到 commit 的数据,所以就导致了“不可重复读”问题
    如果使用 RR 隔离级别,事务D 的两次读取都是 “张三”
    RR 隔离级别是基于 MVCC 实现的,MVCC 又依赖 UNDO_LOGUNDO_LOG就是回滚日志,它是一个版本链,它记录了上一次版本的数据变化
    eg:事务 B 把“张三”改为了“张小三”,在UNDO_LOG 中的体现如下:
    image.png
    注:最原始的数据,也就是最下面这一条,它的 事务ID回滚指针 都是 null
    了解了 UNDO_LOG 之后,现在引入一个新的名词:ReadView(快照读)
    快照都就是普通的 sql 查询语句:select ....
    有了快照读就有当前读,当前读是指:
    Insert、Update、Delete、
    Select ... for update
    Select ... lock in share mode

    ReadView 数据结构

    image.png
    图是从 IT老齐 那儿盗的,稍微解释一下:
    m_ids 未提交的事务,不允许读
    min_trx_id 就是快要执行完的事务 id
    max_trx_id 就是下一个新的事务的 id
    creator_trx_id 就是创建这个 ReadView 是哪个事务

    RC 原理

    RC(读已提交):在每一次执行快照读时生成 ReadView,根据上面的例子
    image.png
    读了两次,生成了两个 ReadView,先看第一个 ReadView,因为在这个 ReadView 生成的时候,事务1 已经 commit 了,所以他不在活跃事务集合里面,所以 m_ids 是 2,3,4
    最小活跃事务就是 2 没有异议
    预分配事务id 就是 4+1 = 5
    当前的 ReadView 是事务 4 创建的,所以 creator_trx_id = 4
    第二个 ReadView 也是一样的的逻辑

    版本链数据访问规则:

    image.png

    RR 原理

    可重复读原理很简单,就是复用 ReadView
    image.png
    eg:在第二次查询的时候,生成的 ReadView 是复用前一次的,所以不会造成 不可重复读

    RR 能解决幻读吗?

    能,但不完全能。
    如果是多次快照读,ReadView会产生复用,没有幻读产生
    但是当多次快照读中间存在当前读,ReadView会重新生成,导致产生幻读
    image.png

  • 相关阅读:
    【Anagrams】 cpp
    【Count and Say】cpp
    【Roman To Integer】cpp
    【Integer To Roman】cpp
    【Valid Number】cpp
    重构之 实体与引用 逻辑实体 逻辑存在的形式 可引用逻辑实体 不可引用逻辑实体 散弹式修改
    Maven项目聚合 jar包锁定 依赖传递 私服
    Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器
    mysql案例~tcpdump的使用
    tidb架构~本地化安装
  • 原文地址:https://www.cnblogs.com/Fzeng/p/16314263.html
Copyright © 2020-2023  润新知