Mysql进阶-InnoDB引擎事务原理及MVCC

这篇具有很好参考价值的文章主要介绍了Mysql进阶-InnoDB引擎事务原理及MVCC。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

事务原理

事务基础

事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系 统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。

 事务的四大特性:

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环 境下运行。
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

我们研究事务的原理,就是研究MySQL的InnoDB引擎是如何保证事务的这四大特性的。 

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 而对于这四大特性,实际上分为两个部分。 其中的原子性、一致性、持久化,实际上是由InnoDB中的 两份日志来保证的,一份是redo log日志,一份是undo log日志。 而隔离性是通过数据库的锁, 加上MVCC来保证的。我们研究事务的原理,主要就是来研究一下redolog,undolog以及MVCC。

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

redo log 

重做日志,记录的是事务提交时数据页的物理修改,是用来实现事务的持久性。 该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中, 用于在刷新脏页到磁盘,发生错误时, 进行数据恢复使用。

如果没有redolog,可能会存在什么问题的? 我们一起来分析一下

我们知道,在InnoDB引擎中的内存结构中,主要的内存区域就是缓冲池,在缓冲池中缓存了很多的数据页。 当我们在一个事务中,执行多个增删改的操作时,InnoDB引擎会先操作缓冲池(Buffer Pool)中的数据,如果缓冲区没有对应的数据,会通过后台线程将磁盘中的数据加载出来,存放在缓冲区中,然后将缓冲池中 的数据修改,修改后的数据页我们称为脏页。 而脏页则会在一定的时机,通过后台线程刷新到磁盘 中,从而保证缓冲区与磁盘的数据一致。 而缓冲区的脏页数据并不是实时刷新的,而是一段时间之后将缓冲区的数据刷新到磁盘中,假如刷新到磁盘的过程出错了,而提示给用户事务提交成功,而数据却没有持久化下来,这就出现问题了,没有保证事务的持久性。

 Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

在InnoDB中提供了一份日志 redo log,接下来我们再来分析一 下,通过redolog如何解决这个问题。 

有了redolog之后,当对缓冲区的数据进行增删改之后,会首先将操作的数据页的变化,记录在redo log buffer中。在事务提交时,会将redo log buffer中的数据刷新到redo log磁盘文件中。 过一段时间之后,如果刷新缓冲区的脏页到磁盘时,发生错误,此时就可以借助于redo log进行数据恢复,这样就保证了事务的持久性。 而如果脏页成功刷新到磁盘或者涉及到的数据已经落盘,此时redolog就没有作用了,就可以删除了,所以存在的两个redolog文件是循环写的。

undo log

回滚日志,用于记录数据被修改前的信息 , 作用包含两个 : 提供回滚(保证事务的原子性) 和 MVCC(多版本并发控制) 。

undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。即会记录到当前操作的相反操作,方便回滚。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

undo log的销毁与存储 

undo log销毁:undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些 日志可能还用于MVCC。

undo log存储:undo log采用段的方式进行管理和记录,存放在前面介绍的rollback segment 回滚段中,内部包含1024个undo log segment。

 MVCC

基本概念

当前读

读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加 锁。对于我们日常的操作,如:select ... lock in share mode(共享锁),select ... for update、update、insert、delete(排他锁)都是一种当前读。

在测试中我们可以看到,即使是在默认的RR隔离级别下,事务A中依然可以读取到事务B最新提交的内 容,因为在查询语句后面加上了 lock in share mode 共享锁,此时是当前读操作。当然,当我们 加排他锁的时候,也是当前读操作。

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

快照读 

简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据, 不加锁,是非阻塞读。

  • Read Committed:每次select,都生成一个快照读。
  • Repeatable Read:开启事务后第一个select语句才是快照读的地方。
  • Serializable:快照读会退化为当前读。

在测试中,我们看到即使事务B提交了数据,事务A中也查询不到。 原因就是因为普通的select是快照 读,而在当前默认的RR隔离级别下,开启事务后第一个select语句才是快照读的地方,后面执行相同的select语句都是从快照中获取数据,可能不是当前的最新数据,这样也就保证了可重复读。 

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

MVCC 

全称 Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本, 使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView

 隐藏字段

当我们创建表时,我们在查看表结构的时候,就可以显式的看到我们声明的字段。 实际上除了我们声明的字段以外,InnoDB还会自动的给我们添加三个隐藏字段及其含义分别是:

而前两个字段是肯定会添加的, 是否添加最后一个字段DB_ROW_ID,得看当前表有没有主键, 如果有主键,则不会添加该隐藏字段

隐藏字段 含义
DB_TRX_ID 最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID。
DB_ROLL_PTR 回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版 本。
DB_ROW_ID 隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。

undolog 

介绍

回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。 当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。 而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。

 版本链

DB_TRX_ID : 代表最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID,是自增的。

DB_ROLL_PTR : 由于这条数据是才插入的,没有被更新过,所以该字段值为null。

然后,有四个并发事务同时在访问这张表。注:undolog日志记录的并不是具体的数据 ,他是要基于当前记录执行该日志才能得到上一版本的数据,这里是为了方便理解,将其指向数据

第一步

当事务2执行第一条修改语句时,会记录undo log日志,记录数据变更之前的样子; 然后更新记录, 并且记录本次操作的事务ID,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本。

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 第二步

当事务3执行第一条修改语句时,也会记录undo log日志,记录数据变更之前的样子; 然后更新记 录,并且记录本次操作的事务ID,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本。

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 第三步

当事务4执行第一条修改语句时,也会记录undo log日志,记录数据变更之前的样子; 然后更新记 录,并且记录本次操作的事务ID,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本。

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 最终我们发现,不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条 记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。

readview

ReadView(读视图)是快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务 (未提交的)id。

ReadView中包含了四个核心字段:

字段 含义
m_ids 当前活跃的事务ID集合
min_trx_id 最小活跃事务ID
max_trx_id 预分配事务ID,当前最大事务ID+1(因为事务ID是自增的)
creator_trx_id ReadView创建者的事务ID

而在readview中就规定了版本链数据的访问规则(trx_id 代表当前undolog版本链对应事务ID):

条件 是否可以访问 说明
trx_id == creator_trx_id 可以访问该版本 成立,说明数据是当前这个事务更改的。
trx_id < min_trx_id 可以访问该版本 成立,说明数据已经提交了。
trx_id > max_trx_id 不可以访问该版本 成立,说明该事务是在 ReadView生成后才开启。
min_trx_id <= trx_id <= max_trx_id 如果trx_id不在m_ids中, 是可以访问该版本的 成立,说明数据已经提交。

 不同的隔离级别,生成ReadView的时机不同:

  • READ COMMITTED :在事务中每一次执行快照读时生成ReadView。
  • REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

 原理分析

RC隔离级别

RC隔离级别下,在事务中每一次执行快照读时生成ReadView。

在事务5中,查询了两次id为30的记录,由于隔离级别为Read Committed,所以每一次进行快照读 都会生成一个ReadView,那么两次生成的ReadView如下,那么这两次快照读在获取数据时,就需要根据所生成的ReadView以及ReadView的版本链访问规则, 到undolog版本链中匹配数据,最终决定此次快照读返回的数据。

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 先来看第一次快照读具体的读取过程:

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 也就是说只要按照readview的访问规则,只要有一个满足规则即可返回对应的快照,根据这一规则mvcc实现读已提交这一事务隔离级别

  •  先匹配Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql这条记录,,这条记录对应的 trx_id为4,也就是将4带入右侧的匹配规则中。 ①不满足 ②不满足 ③不满足 ④也不满足 , 都不满足,则继续匹配undo log版本链的下一条。
  • 再匹配第二条Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql,这条记录对应的trx_id为3,也就是将3带入右侧的匹配规则中。①不满足 ②不满足 ③不满足 ④也 不满足 ,都不满足,则继续匹配undo log版本链的下一条。
  • 再匹配第三条Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql,这条记录对应的trx_id为2,也就是将2带入右侧的匹配规则中。①不满足 ②满足 终止匹配,此次快照 读,返回的数据就是版本链中记录的这条数据。

 RR隔离级别

RR隔离级别下,仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。 而RR 是可重复读,在一个事务中,执行两次相同的select语句,查询到的结果是一样的。

 我们看到,在RR隔离级别下,只是在事务中第一次快照读时生成ReadView,后续都是复用该 ReadView,那么既然ReadView都一样, ReadView的版本链匹配规则也一样, 那么最终快照读返 回的结果也是一样的

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql

 总结

MVCC的实现原理就是通过 InnoDB表的隐藏字段、UndoLog 版本链、ReadView来实现的。 而MVCC + 锁,则实现了事务的隔离性。 而一致性则是由redolog 与 undolog保证。

Mysql进阶-InnoDB引擎事务原理及MVCC,java,数据库,mysql文章来源地址https://www.toymoban.com/news/detail-762368.html

到了这里,关于Mysql进阶-InnoDB引擎事务原理及MVCC的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mysql进阶- InnoDB引擎架构

    InnoDB的逻辑存储结构如下图所示:  1). 表空间 是InnoDB存储引擎逻辑结构的最高层, 如果用户启用了参数      innodb_file_per_table(在 8.0版本中默认开启) ,则每张表都会有一个表空间(xxx.ibd),一个mysql实例可以对应多个表空间, 用于存储记录、索引等数据 。 2).   段 ,分为

    2024年02月04日
    浏览(46)
  • java面经 MySQL 存储引擎--MyISAM和InnoDB的区别

    隔离级别 英文名称 含义 脏读 不 可 重 复读 幻读 未提交读 READ UNCOMMITTED 可读取其它事务未提交的结果 √ √ √ 提交读 READ COMMITTED 一个事务开始时,只能读到其他事务已经提交的修改。 例:如果A事务已经修改了XX,但还没提交,则B事务读XX时还是未修改的值。 ( Oracle等多

    2024年02月08日
    浏览(45)
  • InnoDB是事务型数据库的首选引擎

    支持事务安全表( ACID),支持行锁定和外键; MySQL事务的ACID特性是确保数据准确性和可靠性的基本原则,包括**原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)**。具体如下: 1. **原子性(Atomicity)**:原子性指的是事务作为最小的执行单位,

    2024年03月14日
    浏览(50)
  • mysql事务日志和MVCC

    1.mysql的redolog日志和undolog日志的作用? A redolog主要作用是保证 提交 commit 的数据的成功 将修改的数据在正式 提交 commit 前进行记录 记录的方式,将日志从内存刷新给文件缓存,文件缓存什么时候落盘由操作系统自行决定(2) redolog日志的主要作用保证commit行为的安全性 B undo

    2024年01月22日
    浏览(55)
  • MVCC------Mysql并发事务控制的工具

    MVCC 是 Multi-Version Concurrency Control(多版本并发控制)的缩写,是数据库系统中常用的一种并发控制方法。在MVCC 中,数据库系统可以同时维护多个版本的数据,每个事务在读取数据时会看到一个一致性的快照,从而实现并发访问而不会出现数据不一致的情况。这种机制能够提

    2024年03月14日
    浏览(87)
  • 【MySQL】事务之MVCC(多版本并发控制)

    读-读 :不存在任何问题,也不需要并发控制 读-写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读 写-写 :有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失 多版本并发控制 ( MVCC )是一种用来解决 读

    2024年02月14日
    浏览(46)
  • 从 MySQL 的事务 到 锁机制 再到 MVCC

    Java基础合集 数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 其他系列文章导航 文章目录 前言 一、事务 1.1 含义 1.2 ACID 二、锁机制 2.1 锁分类 2.2 隔离级别 三、MVCC 3.1 介绍 3.2 隔离级别 3.3 原理 四、总结 转眼又一年~~2023马上就要到尾声了,在最后的几天中

    2024年02月03日
    浏览(35)
  • 一文带你了解MySQL之事务隔离级别和MVCC

    为了我们学习的顺利进行,我们这边创建一张 hero 表 这里需要注意的是,我们的 hero 表的主键是 number ,而不是 id ,主要是后边要用到的 事务id 做一下区别,然后我们给这个表里插入一条数据 现在我们表里的数据就是这样: 我们知道 MySQL 是 CS 架构的软件,若干个客户端与

    2024年02月08日
    浏览(69)
  • MySQL事务(4种事务隔离级别、脏写、脏读、不可重复读、幻读、当前读、快照读、MVCC、事务指标监控)

    显示事务: read write:读写事务,默认模式,表示当前事务可以读写数据。 read only:只读事务,很少用,表示当前事务不能修改数据。 with consistent snapshot:一致性快照,在数据库事务中确保事务在执行过程中能看到一个事务开始时的一致数据库状态,避免被其他并发操作影响

    2024年03月10日
    浏览(46)
  • 12. InnoDB引擎底层存储和缓存原理

    本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。 到目前为止,MySQL对于我们来说还是一个黑盒,我们只负责使用客户端发送请求并等待服务器返回结果,表中的数据到底存到了哪里?以什么格式存放的?MySQL是以什么方式来访问的这些

    2024年02月06日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包