MySQL事务篇2:InnoDB引擎

        InnoDB是MySQL的默认存储引擎,支持ACID事务、行级锁定和外键约束,通过多版本并发控制(MVCC)实现高并发性能。InnoDB使用聚簇索引存储数据,具备崩溃恢复能力,确保数据一致性和完整性。其主要特性包括数据和索引的高效管理、可靠的事务处理和强大的并发控制,是处理复杂查询和高并发应用的理想选择。

一、逻辑存储结构

        InnoDB 的逻辑存储结构主要包括以下几个层次:表空间、段、区和页。通过这种多层次的逻辑存储结构,实现了高效的数据存储和管理,支持复杂的事务操作和高并发访问。表空间、段、区和页的分层结构确保了数据的有序组织和快速访问,同时减少了磁盘碎片,提高了整体性能和可靠性。

表空间(Tablespace)
  ├── 段(Segment)
  │    ├── 数据段(Data Segment)
  │    ├── 索引段(Index Segment)
  │    └── 回滚段(Undo Segment)
  ├── 区(Extent)
  │    ├── 页(Page 0)
  │    ├── 页(Page 1)
  │    └── ...
  └── 页(Page 63)

1. 表空间(Tablespace)

表空间是 InnoDB 存储数据的最高层次的逻辑结构。InnoDB 有两种类型的表空间:

  • 共享表空间:所有表的数据和索引存储在一个或多个共享表空间文件(如 ibdata1)。
  • 独立表空间:每个表的数据和索引存储在各自独立的表空间文件(即 .ibd 文件)。

配置参数 innodb_file_per_table 用于设置是使用共享表空间还是独立表空间。

2. 段(Segment)

每个表和索引在表空间中都有自己的段。段是存储特定类型数据的逻辑结构,包括以下几种:

  • 数据段:存储表的实际行数据。
  • 索引段:存储二级索引的数据。
  • 回滚段:存储事务的撤销日志,用于回滚和MVCC。

3. 区(Extent)

区是 InnoDB 分配磁盘存储空间的基本单位,每个区通常为 1MB。区由连续的页组成,用于减少碎片化,提高存储和检索效率。每个区包含 64 个页(每页 16KB)。

4. 页(Page)

页是 InnoDB 存储和管理数据的最小单位,每页大小为 16KB。不同类型的数据存储在不同类型的页中,主要包括:

  • 数据页(Data Page):存储实际行数据。
  • 索引页(Index Page):存储 B+ 树结构的索引数据。
  • 系统页(System Page):存储系统内部信息。
  • 撤销页(Undo Page):存储撤销日志,用于事务回滚。
  • 插入缓冲位图页(Insert Buffer Bitmap Page):存储插入缓冲相关信息。
  • 插入缓冲空闲列表页(Insert Buffer Free List Page):管理插入缓冲的空闲空间。

 

二、事务的原理

        在事务篇1中我们简单的提到过如何保持事务的原子性、一致性、持久性和隔离性,在这章中我们来详细的探讨一下这些都是如何实现的。

2.1 redo log

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

  • 首先,客户端向MySQL服务器发起一次请求,它包含多条SQL语句,然后MySQL服务器的内存缓存池中会判断其中是否有即将修改的数据
  • 如果在缓存区中没有相关的数据则会向磁盘中加载相关的数据
  • 一段时间后,会通过后台线程将数据刷新到磁盘当中
  • 但是数据的刷新并不是实时的,如果数据刷新出错,此时事务已经提交成功,返回给用户端成功信息,则持久性就没有得到保证
  • redolog的出现保证了持久化

问题:为什么在事务提交之后,不直接持久化到磁盘当中呢?

如果每一次事务提交都将缓存区的数据刷新到磁盘当中会有严重的性能问题,因为在一次事务中会操作大量的随机数据页,这些数据页也会产生大量的随机磁盘IO,性能非常低。

如果先异步刷新redolog日志文件,log日志文件都是顺序追加的,不会有很多的随机IO,他是顺序磁盘IO,这种机制就是WAL机制(先写日志)。

 2.2 undo log

        undo log又叫回滚日志,用于记录数据被修改前的信息,他是保证事务原子性的重要手段,他的作用包含两个:提供回滚 和 MVCC(多版本并发控制)。
        undoloq和redoloq记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undolog中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。当执行rollback时,就可以从undolog中的逻辑记录读取到相应的内容并进行回滚。
        Undo log销毁:undolog在事务执行时产生,事务提交时,并不会立即删除undolog,因为这些日志可能还用于MVCC。
        Undo log存储:undolog采用段的方式进行管理和记录,存放在前面介绍的 rollback segment 回滚段中,内部包含1024个undolog segment。

三、MVCC

3.1 读取数据

mysql读取数据实际上有两种读取模式:当前读和快照读

  • 当前读:每次读取的都是当前最新的数据,但是读的时候不允许写,写的时候也不允许读。对于我们日常的操作,如:select .. lock in share mode(共享锁),select....for update、update、insert、delete(排他锁)都是一种当前读。
  • 快照读:读写不冲突,每次读取的是快照数据,简单的select(不加锁)就是快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
    • Read Committed:每次select,都生成一个快照读。
    • Repeatable Read:开启事务后第一个select语句才是快照读的地方,
    • Serializable:快照读会退化为当前读。

隔离级别Repeatable Read下(默认隔离级别可重复读):有可能读取的不是最新的数据
Read Committed隔离级(读提交)别下:快照读和当前读读取的数据是一样的,都是最新的。

3.2 共享锁和排它锁

        共享锁(S锁):共享 (S) 用于不更改或不更新数据的操作(只读操作),如 SELECT 语句。
        如果事务T仅对数据A进行读取,那么会对数据A加上共享锁,之后则其他事务如果要读取数据A的话可以对其继续加共享锁,但是不能加排他锁(也就是无法修改数据)。获准共享锁的事务只能读数据,不能修改数据。
        排他锁(X锁):用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时同一资源进行多重更新。
        如果事务T对数据A要进行修改,则需要对其添加排它锁,加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

3.3 MVCC实现原理

1、隐藏字段

隐藏字段可能有三个也可能有两个,这取决于这张表是否有主键,如果有主键则不会生产DB_ROW_ID这个隐藏主键。

 2、undo log版本链

一条在数据库中的数据都一定会有两个隐藏字段,事务ID与回滚指针,每提交一个事务就会有一个修改之前的数据提交到undolog中并且新数据回滚指针指向它。

3、readview

 

接下来看版本链数据访问规则,这readview的核心,也是快照读的核心

 

来看RC隔离级别下具体用法,首先在执行的快照读生产ReadView,ReadView会有上面那四个信息,然后去undolog中对比可使用版本进行访问。 

 

 

讲解到这应该就可以明白了,事务篇1中我们提到过,MySQL的RR隔离级别也能避免大部分的幻读,这就是因为MVCC中readview与undolog日志配合来实现的,RR隔离级别下的快照读定格了一条数据,即使后续有并发事务修改,读取的也是之前快照读定格的那一条数据。

事务篇2InnoDB引擎结束,感谢观看,如有错误欢迎斧正。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/649652.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

今日选题。

诱导读者点开文章的9引真经(一) 标题重要么?新媒体、博客文通常在手机上阅读。首先所有的内容不同于纸媒,手机只展现标题,而内容都是折叠。其次读者能像看内容一样看4、5条或者7、8条标题(区别于不同的主流…

2024年流行效果插件,助你打造非凡设计!

设计图片太普通了?加班挑细节?你不能达到你想要的效果吗?作为一名设计师,你总是无法逃脱这样的噩梦!如何改变工作中的类似困境?除了提高自我设计技能外,选择一些辅助效果插件“插件”也非常重要…

CSS 【实战】 “四合院”布局

效果预览 页面要求: 上下固定高度左右固定宽度中间区域自适应宽高整个页面内容撑满全屏,没有滚动条 技术要点 使用 html5 语义化标签 header 网页内的标题区域nav 导航区域aside 侧边栏footer 页脚区域section 内容分区article 文章区域 清除浏览器默…

【实战JVM】-基础篇-02-类的声明周期-加载器

【实战JVM】-基础篇-02-类的声明周期-加载器 3 类的生命周期3.1 生命周期的概述3.2 加载阶段3.2.1 查看内存中的对象 3.3 连接阶段3.3.1 验证阶段3.3.1.1 验证是否符合jvm规范3.3.1.2 元信息验证3.3.1.3 验证语义3.3.1.4 符号引用验证 3.3.2 准备阶段3.3.3 解析阶段 3.4 初始化…

LangChain实战技巧之三:关于Tool的一点拓展

(几乎)任一LLM在bind_tools时,都是习惯先定义一个Function或BaseTool,然后再bind(bind_tools)具体方式可参考我的这篇文章 AI菜鸟向前飞 — LangChain系列之十三 - 关于Tool的必知必会 但这里的tool未必需…

Python代码:十九、列表的长度

1、题目 描述: 牛牛学会了使用list函数与split函数将输入的连续字符串封装成列表,你能够帮他使用len函数统计一些公输入了多少字符串,列表中有多少元素吗? 输入描述: 输入一行多个字符串,字符串之间通过…

猫狗分类识别模型建立①数据标记

一、labelImg库说明 LabelImg是一款非常流行的图像标注工具,广泛用于机器学习和计算机视觉领域。以下是关于LabelImg的详细介绍: 主要功能和特点 1.图像标注 允许用户在图像中标注物体,选择特定区域,并为这些区域添加标签或类…

虚拟列表 vue-virtual-scroller 的使用

npm 详情&#xff1a;vue-virtual-scroller - npm (npmjs.com) 这里我使用的是RecycleScroller。 App.vue <template><RecycleScrollerclass"scroller":items"items":item-size"54"v-slot"{ item }"><list-item :it…

Vue框架动态引入省份个性化代码

项目需求有产品的功能&#xff0c;但是功能下部分小功能每个省份有不同的控制&#xff0c;所以需要引入省份个性化代码。 思路是&#xff0c;页面一开始加载产品化的代码&#xff0c;有个性化的代码就加载个性化的逻辑&#xff0c;个性化代码是产品化代码的重写&#xff0c;所…

网络协议——FTP(简介、搭建FTP服务端)

一、简介 1、什么是FTP&#xff1f; FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09; TCP/IP 协议组的协议之一。常用20&#xff08;数据&#xff09;、21&#xff08;命令&#xff09;端口作为通讯端口。&#xff08;22为SSH端口&#xff09;F…

机器学习入门指南:Jupyter Notebook实战

前言 机器学习作为人工智能领域的核心组成&#xff0c;是计算机程序学习数据经验以优化自身算法、并产生相应的“智能化的“建议与决策的过程。随着大数据和 AI 的发展&#xff0c;越来越多的场景需要 AI 手段解决现实世界中的真实问题&#xff0c;并产生我们所需要的价值。 机…

引力为什么会让时间变慢,给你通俗的解读

爱因斯坦的狭义相对论表明&#xff0c;速度会让时间变慢&#xff0c;速度越快时间就越慢。而广义相对论告诉我们&#xff0c;引力同样会让时间变慢&#xff0c;引力越强时间就越慢。 时间膨胀 速度对时间的影响就先不解释了&#xff0c;之前的科普文章介绍了很多&#xff0c;今…

【C++】从零开始map与set的封装

送给大家一句话&#xff1a; 今日的事情&#xff0c;尽心、尽意、尽力去做了&#xff0c;无论成绩如何&#xff0c;都应该高高兴兴地上床恬睡。 – 三毛 《亲爱的三毛》 &#x1f303;&#x1f303;&#x1f303;&#x1f303;&#x1f303;&#x1f303;&#x1f303;&#x…

看潮成长日程表用户手册(下)

看潮成长日程表用户手册&#xff08;下&#xff09; 四、基础设置1、系统用户设置2、成长学员设置3、自然期间定义4、时间表版本设置5、学员期间设置6、时间表时段设置7、年度假日维护 五、参数设置1、颜色参数设置2、逻辑参数设置3、数值参数设置4、字符参数设置5、列表输入项…

【二分查找 位运算】3145. 大数组元素的乘积

本文涉及知识点 二分查找算法合集 位运算、状态压缩、枚举子集汇总 LeetCode3145. 大数组元素的乘积 一个整数 x 的 强数组 指的是满足和为 x 的二的幂的最短有序数组。比方说&#xff0c;11 的强数组为 [1, 2, 8] 。 我们将每一个正整数 i &#xff08;即1&#xff0c;2&am…

c语言从入门到函数速成(完结篇)

哈喽&#xff0c;小伙伴们大家好呀&#xff0c;本篇文章是这个系列的完结篇&#xff0c;希望大家看完后能有所收获哦 首先能看到这里的同学&#xff0c;一定也是自觉性比较强的了&#xff0c;我会在文章末尾给大家发点小福利 那么&#xff0c;我们先来通过数学中的函数来引入一…

医学中脑机接口技术的未来

医学中脑机接口技术的未来 李升伟 编译 对非侵入性脑机接口&#xff08;而不是植入物&#xff09;日益增长的兴趣可能会提高患者的易使用性&#xff0c;但分辨率需要提高。 图片来源&#xff1a;Denis Pobytov / DigitalVision Vectors / Getty 全球范围内正在展开一场争夺利用…

云服务器购买之后到部署项目的流程

1.通过账号密码登录百度智能云控制台; 2.进入对应的服务器‘云服务器BBC’ 找到’实例‘即找到对应的服务器列表; 此时通过本地电脑 1.cmd命令提示符 PING 服务器公网地址不通&#xff1b; 2.通过本地电脑进行远程桌面连接不通 原因&#xff1a;没有关联安全组&#xff0c;或者…

测试基础02:软件开发流程及模型、敏捷开发

1、软件开发流程 包括&#xff1a;项目开发目的分析与确定、需求分析、设计、编程、软件测试、软件交付、验收和维护。 2、软件开发模型 2.1 定义 软件开发模型(Software Development Model)是软件开发全过程的框架&#xff0c;规定了软件开发过程中各项活动的基本步骤、任务…

InteractiveGraph图谱中vue项目中如何使用

InteractiveGraph图谱中vue项目中如何使用 一、下载js和css和字体二、vue2.0项目中引用三、grap组件 一、下载js和css和字体 //在这里面找 https://github.com/grapheco/InteractiveGraph/blob/master/dist/examples/example1.html二、vue2.0项目中引用 //main.js中全局引入$ …