【MySQL是怎样运行的 | 第三篇】MySQL的MVCC机制

文章目录

3.MySQL的MVCC机制

3.1前言

  1. MVCC,在数据库中实现并发控制的技术,允许多个事务同时对数据库进行读写操作,而不会导致数据不一致或丢失
  2. 核心思想:在数据库中维护多个数据版本,并根据事务的隔离级别来决定哪个版本数据对特定事务是可见的
  3. 实现的四个重要部分:
    1. undo log日志
    2. 隐藏字段
    3. undo log版本链
    4. readView

3.2undo log日志

  1. undo log(回滚日志)中记录了修改前的数据值,以及撤销操作所需的信息,以便在事务回滚或 MVCC 中使用

3.3三个隐藏字段

  1. InnoDB会自动为每个undo log 回滚日志加上三个字段:
    1. DB_ROW_ID:隐藏主键
    2. DB_TRX_ID:创建该undo log 版本数据的事务ID
    3. DB_ROLL_PTR:回滚指针,指向这个事务之前的 undo log

3.4undo log版本链

  1. undo log 版本链:基于undo log 回滚日志实现,维护了一条数据的多个版本

3.5当前读VS快照读

  1. 当前读

    1. 读取的是当前记录的最新版本,读取的时候需要保证其他并发事务不能修改当前记录,对当前记录加锁
    2. 例子:Insert、Update、Delete、Select... for update(写锁)、Select... lock in share mode(读锁)
  2. 快照读:

    1. 最普通的Select查询SQL语句
    2. 读取的是数据的可见版本,有可能是历史数据、当前版本,不加锁,是非阻塞读
    3. 底层依赖:当执行"快照读"SQL语句时,依据ReadView(快照) 来提取数据

3.6ReadView

  1. ReadView,一个保存事务ID的list列表。记录的是本事务执行时,MySQL还有哪些事务在执行,且还没有提交
  2. 一种数据结构,包含四个字段:
    1. m_ids:当前活跃的事务编号集合
    2. min_trx_id:最小活跃事务编号
    3. max_trx_id:预分配事务编号,即当前最大事务编号+1
    4. creator_trx_id:ReadView创建者的事务编号
  3. 不同隔离级别下快照生成的时机:
    1. RC(读已提交):每一次select,都生成一个 ReadView
    2. RR(可重复读):开启一个事务之后,只有第一个select语句才会生成一张快照,此后读的都是快照中的数据,直到事务提交
    3. Serializable(可序列化):快照读退化成当前读(加锁,阻塞,读取到的是最新的数据)
  4. 根据ReadView快照访问undo log 版本链数据的规则:
    1. 若 trx_id==creator_trx_id?可以访问该版本,因为数据是当前这个事务更改的;
    2. 若 trx_id < min_trx_id?可以访问该版本,因为数据已经提交了;
    3. 若 trx_id > max_trx_id?不可以访问该版本,因为该事务修改的数据是在 ReadView生成后才开启的;
    4. 若 min_trx_id<=trx_id<=max_trx_id 并且 trx_id不在 m_ids(活跃事务编号集合)中,可以访问该版本,因为该数据已经提交;

3.7举例

3.7.1RC(读已提交)

  1. 其中事务4的两次快照读均会产生ReadView,如下:
  1. 分析第一个ReadView:
  1. 分析第二个ReadView:
  1. 小结:

    1. 在RC(读已提交)的事务隔离级别下,同一事务的两次快照读均会产生两个快照(ReadView);
    2. 第一个快照读读取的数据是 事务一修改并提交的数据:张三
    3. 第二个快照读读取的数据是 事务二修改并提交的数据:张小三
    4. 同一事务的两个不同select(快照读)读取的数据不一样,产生不可重复读现象
  2. 思考:应该怎么解决?

  3. 解决:设置隔离级别为 RR(可重复读),同一事务从始至终只会生成一个快照

3.7.2RR(可重复读)

  1. 隔离级别为 RR(可重复读),同一事务从始至终只会生成一个快照,即不会产生 不可重复读问题

3.8扩展:RR能解决幻读问题吗?

  1. 结论:RR(可重复读)可以解决一部分幻读问题

  2. 原因:

    1. 同一事务的连续多次快照读,ReadView会产生复用,没有幻读问题

    2. 特例:当两次快照读之间存在当前读,ReadView会重新生成,导致幻读问题

4.白云

相关推荐
yueqingll11 分钟前
020、二级Java选择题综合知识点(持续更新版)
java·开发语言
Cedric_Anik17 分钟前
MYSQL数据库基础篇——DDL
数据库·mysql
文牧之17 分钟前
PostgreSQL的walsender和walreceiver进程介绍
运维·数据库·postgresql
爬山算法20 分钟前
Oracle(121)如何进行数据文件的恢复?
数据库·oracle
咔咔学姐kk22 分钟前
2024最新版,人大赵鑫老师《大语言模型》新书pdf分享
数据库·人工智能·语言模型·自然语言处理·pdf·知识图谱·产品经理
许野平38 分钟前
Rust:深入浅出说一说 Error 类型
java·开发语言·rust·error
jingling55542 分钟前
后端开发刷题 | 数字字符串转化成IP地址
java·开发语言·javascript·算法
青云交1 小时前
大数据新视界 --大数据大厂之MongoDB与大数据:灵活文档数据库的应用场景
大数据·数据库·mongodb·非关系型数据库·文档存储·查询功能、数据处理·开发效率、应用场景、高可扩展性
青云交1 小时前
大数据新视界 --大数据大厂之HBase深度探寻:大规模数据存储与查询的卓越方案
大数据·数据库·hbase·数据存储·性能优势、问题解决、应用领域·可扩展性、高可靠性·读写性能、集群管理
茜茜西西CeCe1 小时前
大数据处理技术:HBase的安装与基本操作
java·大数据·数据库·hbase·头歌·大数据处理技术