MySQL高级12-事务原理

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

一、事务概念

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

二、事务特性

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

三、事务的隔离级别

  • 读未提交(Read Uncommitted):最低的隔离级别,事务可以读取到其他事务尚未提交的数据,存在脏读(Dirty Read)问题,即读取到未提交的数据,可能导致数据的不一致性。
  • 读已提交(Read Committed):事务只能读取到其他事务已经提交的数据,解决了脏读的问题,但是可能导致不可重复读(Non-Repeatable Read)问题,即在同一事物中多次读取同一数据时可能会得到不同的结果。
  • 可重复读(Repeatable Read):可重复读是MySQL默认的隔离级别,并且解决了不可重复读问题,在一个事务中,多次读取同一数据会得到相同的结果,及时其他事务更改了数据。
  • 串行化读(Serializable):最高的隔离级别,强制所有事务按照顺序依次执行,避免了脏读,不可重读和幻读(Phantom Read),幻读指在同一事务中,多次查询同一个范围的数据时,结果集合的行数可能不一致。

四、Redo Log

  在MySQL中,Redo Log和Undo Log是用来支持事务和保证数据一致性的关键日志机制。

  Redo Log(重做日志): 作用是记录了所有对数据库的修改操作,包括插入、更新和删除等操作。记录了事务提交时数据页的物理修改,是用来实现事务的持久性

  该日志文件有两部分组成:重做日志缓冲(Redo Log Buffer)以及重做日志文件(Redo Log File),前者是在内存中,后者在磁盘中,当事务提交之后会把所有信息都存到该日志文件中,用户刷新脏页到磁盘,发生错误时,进行数据恢复使用。

  工作原理:当事务进行数据修改时,MySQL将修改的操作记录到 Redo Log中,而不直接写入磁盘的数据文件中。这样可以减少磁盘IO的操作,提高性能。在事务提交时,Redo Log的内容会被异步刷新到磁盘上的数据文件中,确保数据的持久性。如果系统崩溃,MySQL可以通过Redo Log中的信息重做之前未写入磁盘的修改操作,恢复到事务提交的状态。

五、Undo Log

  5.1 简介

    Undo Log(回滚日志):用来支持事务的回滚操作,即将事务的修改操作撤销,恢复到之前的状态。在insert、update、delete的时候产生的便于数据回滚的日志。

    当insert的时候,产生的 Undo Log日志只在回滚时需要,在事务提交后,可被立即删除。

    而update、delete的时候,产生的Undo Log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。

    工作原理:当事务进行数据修改时,MySQL将修改的操作记录到Undo Log中,并在事务提交之前保留这些修改的记录。如果事务发生回滚操作,MySQL会根据Undo Log中的信息,将事务的修改操作撤销,将数据还原到事务开始的状态。因此,Undo Log为事务提供了撤销操作的能力,确保数据库的一致性。

  5.2 Undo Log 版本链

    不同事务或相同事务对同一条记录进行修改,会导致该记录的Undo Log生成一条记录版本链,链表的头部是最新的旧记录,链表尾部是最早的旧记录

    MySQL高级12-事务原理

     说明1:第一次insert的数据,此时DB_TRX_ID 为1, 因为还没有修改过,所以DB_ROLL_PTR为null

    MySQL高级12-事务原理

     说明2:此时我们模拟几个并发同时开始的事务

    MySQL高级12-事务原理

     说明3:此时我们在事务2中修改id为30的数据

    MySQL高级12-事务原理

    说明4:那么在执行修改操作之前,会先把原始数据写入Undo Log日志中一份,方便数据回滚

    说明5:在此时原始记录中age改为3,并且隐藏字段DB_TRX_ID变为2,DB_ROLL_PTR在为Undo Log 日志中的第一条数据的地址

    MySQL高级12-事务原理

     说明6:此时事务2提交事务之后,事务3又修改id为30的数据,name改为A3

  MySQL高级12-事务原理

    说明7:此时在更改原始数据之前,需要把当前的数据在写入到Undo Log日志中一份,继续方便做数据回滚,而这时Undo Log中就有了两条数据

    说明8:然后就可以修改原始数据 name 改为 A3,并且DB_TRX_ID也改为3,DB_ROLL_PTR指向Undo Log第二条日志的地址。

    说明9:这样就形成了一条完整的Undo Log版本链 

六、MVCC

  6.1 当前读

    读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行枷锁。

    如:select...lock in share mode(共享锁)、select...for update、update、insert、delete(排他锁)都是一种当前读。

    MySQL高级12-事务原理

   6.2 快照读

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

    • Read Committed:每次select,都生成一个快照读。
    • Repeatable Read:开启事务后第一个select语句就会生成一个快照读,其后面的select读取的都是快照中的数据,所以数据才是可重复读的。
    • Serializable:快照读会退化为当前读      

  6.3 MVCC

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

  6.4 记录中的三个隐藏字段   

    示例如下: 

   MySQL高级12-事务原理

    DB_TRX_ID:最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID

    DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本,用于配合Undo Log,指向上一个版本

    DB_ROW_ID:隐式主键,如果表结构没有指定主键,将会生成该隐藏字段

    使用指令重新创建一个表mvcc_test,这个时候不给该表设置主键

    MySQL高级12-事务原理

    然后在数据库路径下的data文件夹下就可以找到我们刚创建的独立表结构空间mvcc_test.ibd

    MySQL高级12-事务原理

     MySQL提供了一个ibd2sdi 指令可以查看表结构空间

root@ubuntu:/usr/local/mysql/data/mysql_test# ibd2sdi mvcc_test.ibd 
["ibd2sdi",
{
    ...                                     # 这里的 ... 是我过滤掉的无关数据
    "dd_object_type": "Table",              # 这里说明这是一个表结构
    "dd_object": {
        "name": "mvcc_test",           # 名称 mvcc_test
        ...
        "columns": [                        # 所有的列
            {
                "name": "name",             # 自己定义的name列
               ... 
            },
            {
                "name": "DB_ROW_ID",         # 隐式创建的列
                ...
            },
            {
                "name": "DB_TRX_ID",         # 隐式创建的列,如果在创建表的时候指定了主键,则该隐藏字段就不会被创建
                 ...
            },
            {
                "name": "DB_ROLL_PTR",       # 隐式创建的列
                 ...
            }
        ],
        "schema_ref": "mysql_test",          # 该表所属的数据库
      ...
    }
}
] root@ubuntu:/usr/local/mysql/data/mysql_test#

七、readView

  7.1 readView(读视图)

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

  7.2 readView中的四个核心字段

    • m_ids:当前活跃的事务ID集合,即当前未提交的事务的ID集合。
    • min_trx_id:最小活跃事务ID。
    • max_trx_id:预分配事务ID,当前最大事务ID+1,因为事务ID是自增的。
    • creator_trx_id:readView创建者的事务ID。

   7.3 版本链数据访问规则

    • 当前事务ID == creator_trx_id 可以访问该版本:因为当前事务的id=creator_trx_id说明这个版本就是当前事务创建的。
    • 当前事务ID < min_trx_id 可以访问该版本:因为当前事务ID小于当前正在活跃事务的最小ID,说明当前事务已经提交了,并且该版本是在当前时候提交后才创建,所以可以访问。
    • 当前事务ID > max_trx_id 不可以访问该版本:因为当前事务ID比readView最大的活跃ID还大,说明当前事务是在readVIew创建之后才开启的,所以不能访问以前的还未提交事务的数据。
    • 当前事务ID >= min_trx_id 并且 <= max_trx_id 并且不在m_ids中 可以访问该版本:因为不在m_ids中说明数据已经提交了,并且<= max_trx_id 又说明不是在readView创建之后开启的,所以可以访问。

  7.4 不同隔离级别,生成readView的时机不同

    • read committed:在事务中每一次执行快照读时生成readView。
    • repeatable read:仅在事务中第一次执行快照读时生成readView,后续复用该readView。

   7.5 read committed隔离级别下readView查询数据的机制

    因为read committed 模式下, 在事务中每一次执行快照读时都会生成readView.所以在同一个事务下,读取两次数据,就会产生两个ReadVIew

    MySQL高级12-事务原理

 文章来源地址https://www.toymoban.com/news/detail-709956.html

    说明1:以事务5的两次查询为例

    说明2:ReadView1中的m_ids:[3,4,5],因为事务2在开启该次查询事务的事就已经提交了,所以m_ids中不包括2,同样的在ReadView2创建的时候,事务3也已经提交,所以ReadView2中的m_ids只有[4,5]

    说明3:套用版本链访问数据的规则,ReadView1和ReadView2两次查询数据演示

    说明4:ReadView1数据查询演示

    1. 使用DB_TRX_ID=4 的数据进行验证,4 不等于 creator_trx_id(5),所以第一个原则不满足
    2. 使用DB_TRX_ID=4 的数据进行验证,4 不小于 min_trx_id(3), 所以第二个原则也不满足
    3. 使用DB_TRX_ID=4 的数据进行验证,4 不大于 max_tr_id(6), 满足第三个原则,但是第三个原则是判断不能访问的,就算着这里满足也不一定能访问,还要看第四个原则
    4. 使用DB_TRX_ID=4 的数据进行验证,4 满足 >=3 并且 <=6 , 但是4在m_ids[3,4,5]中,所以ReadVIew1不能使用DB_TRX_ID = 4 的数据,通过表格也可以看出开在ReadView1查询的时候,事务4并没有提交呢
    5. 使用DB_TRX_ID=3 的数据进行验证,3 不等于 creator_trx_id(5),所以第一个原则不满足
    6. 使用DB_TRX_ID=3 的数据进行验证,3 不小于 min_trx_id(3), 所以第二个原则也不满足
    7. 使用DB_TRX_ID=3 的数据进行验证,3 不大于 max_tr_id(6), 满足第三个原则,但是第三个原则是判断不能访问的,就算着这里满足也不一定能访问,还要看第四个原则
    8. 使用DB_TRX_ID=3 的数据进行验证,3 满足 >=3 并且 <=6 , 但是3在m_ids[3,4,5]中,所以ReadVIew1不能使用DB_TRX_ID = 3 的数据,通过表格也可以看出开在ReadView1查询的时候,事务3并没有提交呢
    9. 使用DB_TRX_ID=2 的数据进行验证,2 不等于 creator_trx_id(5),所以第一个原则不满足
    10. 使用DB_TRX_ID=2 的数据进行验证,2 小于 min_trx_id(3), 所以第二个原则满足,则可以判断ReadView1使用的是 DB_TRX_ID = 2的数据,即id=30, age=3,name=A30

    说明5:ReadView2数据查询演示

    1. 使用DB_TRX_ID=4 的数据进行验证,4 不等于 creator_trx_id(5),所以第一个原则不满足
    2. 使用DB_TRX_ID=4 的数据进行验证,4 不小于 min_trx_id(4), 所以第二个原则也不满足
    3. 使用DB_TRX_ID=4 的数据进行验证,4 不大于 max_tr_id(6), 满足第三个原则,但是第三个原则是判断不能访问的,就算着这里满足也不一定能访问,还要看第四个原则
    4. 使用DB_TRX_ID=4 的数据进行验证,4 满足 >=4 并且 <=6 , 但是4在m_ids[4,5]中,所以ReadVIew2不能使用DB_TRX_ID = 4 的数据,通过表格也可以看出开在ReadView2查询的时候,事务4并没有提交呢
    5. 使用DB_TRX_ID=3 的数据进行验证,3 不等于 creator_trx_id(5),所以第一个原则不满足
    6. 使用DB_TRX_ID=3 的数据进行验证,3 不小于 min_trx_id(4), 所以第二个原则满足,则可以判断ReadView2使用的是 DB_TRX_ID = 3的数据,即id=30, age=3,name=A3。

  7.6 repeatable read 隔离级别下readView查询数据的机制

    repeatable read:仅在事务中第一次执行快照读时生成readView,后续复用该readView,所以这里只会产生一个ReadVIew

    MySQL高级12-事务原理

     说明6:因为这里的数据查询演示过程个上面的一样,只不过这里只有一个ReadVIew,过程更简单。

八、事务的实现原理

  8.1 MVCC的实现原理

    三个隐藏字段+Undo Log版本链+ReadView是MVCC的实现原理

  8.2 事务隔离性的实现原理

    MVCC+锁就是事务隔离性的实现原理

  8.3 事务原子性、一致性实现原理

    Undo Log + Read Log

  8.4 事务的持久性实现原理

    Read Log

 

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

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

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

相关文章

  • Mysql事务原理与优化

    我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。 这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事务隔离机制、

    2024年02月22日
    浏览(28)
  • MYSQL 事务的底层原理

    在事务的实现机制上,MySQL 采用的是 WAL:Write-ahead logging,预写式日志,机制来实现的。 在使用 WAL 的系统中,所有的修改都先被写入到日志中,然后再被应用到系统中。通常包含 redo 和 undo 两部分信息。 为什么需要使用 WAL,然后包含 redo 和 undo 信息呢?举个例子,如果一个

    2024年02月05日
    浏览(33)
  • 【MySql】MySql事务常见操作

    将mysql的默认隔离级别设置成读未提交 注意:设置完毕之后,需要重启终端,进行查看 创建测试表 并且同时启动两个客户端,即两个SSH渠道。 先查看当前事务的提交方式:这里我们之前设置成自动提交了 启动事务: 创建一个保存点: 现在,我们给一端插入数据并且设置保存

    2024年02月10日
    浏览(63)
  • MySQL事务:原理、类型和使用场景

    一、事务的概念 在数据库中,事务是指一组数据库操作,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单元。事务具有ACID(原子性、一致性、隔离性和持久性)特性,保证了数据库操作的正确性和可靠性。 二、事务的特性 原子性(Atomicity) 原子性是指

    2024年02月02日
    浏览(25)
  • MySQL 事务的操作指南(事务篇 二)

    事务的提交方式:自动提交(@@autocommit=1)和手动提交(@@autocommit=0) 查询和修改事务提交方式: 事务基本操作 初始状态: 事务操作(要把事务操作变为手动提交) 执行结果 :还是初始状态,因为事务处理过程报错会回滚 不开启事务执行: 执行结果 :发现数据逻辑出错

    2024年02月07日
    浏览(30)
  • 面试官:请说一下Mysql事务实现原理

    在日常工作中,数据库是我们必须使用的,其中使用最多的也是大部分中小公司的选择是Mysql,跳槽面试中也是必问的,今天我们就说一下Mysql事务 MySQL中的事务实现原理主要涉及以下几个方面: ACID特性:MySQL支持事务的原因之一是它遵循ACID(原子性、一致性、隔离性和持久

    2024年02月02日
    浏览(29)
  • MySQL 篇-深入了解事务四大特性及原理

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍     文章目录         1.0 事务的概述         2.0 事务的特性         2.1 原子性         2.2 一致性         2.3 持久性         2.4 隔离性         2.4.1 脏读问题         2.4.2 不可重复读问题  

    2024年03月22日
    浏览(31)
  • Mysql进阶-InnoDB引擎事务原理及MVCC

    事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系 统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。  事务的四大特性: 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败

    2024年02月04日
    浏览(27)
  • MySQL— 基础语法大全及操作演示!!!(事务)

    MySQL— 基础语法大全及操作演示!!! 1、MySQL概述 2、SQL 3、函数 4、约束 5、多表查询 6、事务 MySQL进阶 —— 超详细操作演示!!! 1、存储引擎 2、索引 3、SQL 优化 4、视图 / 存储过程 / 触发器 5、锁 6、InnoDB 引擎 7、MySQL 管理 6.1 事务简介 事务 是一组操作的集合,它是一个

    2024年02月10日
    浏览(33)
  • [MySQL]事务原理之redo log,undo log

    🌈键盘敲烂,年薪30万🌈 目录 一、log日志文件 📕 事务执行流程 📕 redo log 📕 undo log 二、总结 👀再来一遍ACID 1. 原子性: 原子性确保事务作为一个整体执行,要么全部执行成功,要么全部不执行。 2. 一致性: 一致性确保事务将数据库从一个状态转换为另一个状态。 3.

    2024年02月04日
    浏览(26)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包