📖
R‘Notes
  • 关于本仓库/网站
  • Note
    • Golang的知识碎片
      • 关于Golang的一些碎片知识
    • LeetCode
      • LCR 121. 寻找目标值 - 二维数组
      • LCR 125. 图书整理 II
      • LCR 127. 跳跃训练
      • LCR 143. 子结构判断
      • LCR 159. 库存管理 III
      • LCR 161. 连续天数的最高销售额
      • LCR 170. 交易逆序对的总数
      • LCR 174. 寻找二叉搜索树中的目标节点
      • LeetCode--1. 两数之和
      • LeetCode--10. 正则表达式匹配
      • LeetCode--1004. 最大连续1的个数 III
      • LeetCode--101. 对称二叉树
      • LeetCode--102. 二叉树的层序遍历
      • LeetCode--1027. 最长等差数列
      • LeetCode--103. 二叉树的锯齿形层序遍历
      • LeetCode--1035. 不相交的线
      • LeetCode--104. 二叉树的最大深度
      • LeetCode--1044. 最长重复子串
      • LeetCode--105. 从前序与中序遍历序列构造二叉树
      • LeetCode--106. 从中序与后序遍历序列构造二叉树
      • LeetCode--110. 平衡二叉树
      • LeetCode--111. 二叉树的最小深度
      • LeetCode--112. 路径总和
      • LeetCode--113. 路径总和 II
      • LeetCode--1137. 第 N 个泰波那契数
      • LeetCode--114. 二叉树展开为链表
      • LeetCode--1143. 最长公共子序列
      • LeetCode--115. 不同的子序列
      • LeetCode--1191. K 次串联后最大子数组之和
      • LeetCode--120. 三角形最小路径和
      • LeetCode--121. 买卖股票的最佳时机
      • LeetCode--1218. 最长定差子序列
      • LeetCode--122. 买卖股票的最佳时机 II
      • LeetCode--1220. 统计元音字母序列的数目
      • LeetCode--123. 买卖股票的最佳时机 III
      • LeetCode--124. 二叉树中的最大路径和
      • LeetCode--125. 验证回文串
      • LeetCode--128. 最长连续序列
      • LeetCode--1289. 下降路径最小和 II
      • LeetCode--129. 求根节点到叶节点数字之和
      • LeetCode--1301. 最大得分的路径数目
      • LeetCode--1312. 让字符串成为回文串的最少插入次数
      • LeetCode--134. 加油站
      • LeetCode--135. 分发糖果
      • LeetCode--136. 只出现一次的数字
      • LeetCode--138. 随机链表的复制
      • LeetCode--139. 单词拆分
      • LeetCode--14. 最长公共前缀
      • LeetCode--141. 环形链表
      • LeetCode--142. 环形链表 II
      • LeetCode--143. 重排链表
      • LeetCode--144. 二叉树的前序遍历
      • LeetCode--145. 二叉树的后序遍历
      • LeetCode--146. LRU 缓存
      • LeetCode--148. 排序链表
      • LeetCode--15. 三数之和
      • LeetCode--151. 反转字符串中的单词
      • LeetCode--152. 最大乘积子数组【DP】
      • LeetCode--153. 寻找旋转排序数组中的最小值
      • LeetCode--155. 最小栈
      • LeetCode--1584. 连接所有点的最小费用,最小生成树模板题
      • LeetCode--1594. 矩阵的最大非负积
      • LeetCode--16. 最接近的三数之和
      • LeetCode--160. 相交链表
      • LeetCode--162. 寻找峰值
      • LeetCode--165. 比较版本号
      • LeetCode--169. 多数元素
      • LeetCode--174. 地下城游戏
      • LeetCode--179. 最大数
      • LeetCode--1824. 最少侧跳次数
      • LeetCode--188. 买卖股票的最佳时机 IV
      • LeetCode--189. 轮转数组
      • LeetCode--19. 删除链表的倒数第 N 个结点,关于删除链表会遇见的指针问题
      • LeetCode--1964. 找出到每个位置为止最长的有效障碍赛跑路线
      • LeetCode--198. 打家劫舍
      • LeetCode--199. 二叉树的右视图
      • LeetCode--2. 两数相加
      • LeetCode--20. 有效的括号
      • LeetCode--200. 岛屿数量
      • LeetCode--206. 反转链表
      • LeetCode--207. 课程表
      • LeetCode--208. 实现 Trie (前缀树)
      • LeetCode--209. 长度最小的子数组
      • LeetCode--21. 合并两个有序链表,关于链表的复习
      • LeetCode--210. 课程表 II
      • LeetCode--213. 打家劫舍 II
      • LeetCode--2140. 解决智力问题
      • LeetCode--215. 数组中的第K个最大元素
      • LeetCode--22. 括号生成
      • LeetCode--221. 最大正方形
      • LeetCode--2218. 从栈中取出 K 个硬币的最大面值和
      • LeetCode--224. 基本计算器
      • LeetCode--225. 用队列实现栈
      • LeetCode--226. 翻转二叉树
      • LeetCode--2266. 统计打字方案数
      • LeetCode--227. 基本计算器 II
      • LeetCode--23. 合并 K 个升序链表【堆和分治】
      • LeetCode--230. 二叉搜索树中第 K 小的元素
      • LeetCode--2304. 网格中的最小路径代价
      • LeetCode--232. 用栈实现队列
      • LeetCode--2320. 统计放置房子的方式数
      • LeetCode--2321. 拼接数组的最大分数
      • LeetCode--233. 数字 1 的个数
      • LeetCode--234. 回文链表
      • LeetCode--236. 二叉树的最近公共祖先
      • LeetCode--239. 滑动窗口最大值,关于单调队列的复习
      • LeetCode--24. 两两交换链表中的节点
      • LeetCode--240. 搜索二维矩阵 II
      • LeetCode--2435. 矩阵中和能被 K 整除的路径
      • LeetCode--2466. 统计构造好字符串的方案数
      • LeetCode--25. K 个一组翻转链表
      • LeetCode--2533. 好二进制字符串的数量
      • LeetCode--256. 粉刷房子
      • LeetCode--2606. 找到最大开销的子字符串
      • LeetCode--265. 粉刷房子 II
      • LeetCode--2684. 矩阵中移动的最大次数
      • LeetCode--279. 完全平方数【动态规划】
      • LeetCode--283. 移动零
      • LeetCode--287. 寻找重复数
      • LeetCode--295. 数据流的中位数
      • LeetCode--297. 二叉树的序列化与反序列化
      • LeetCode--3. 无重复字符的最长子串
      • LeetCode--300. 最长递增子序列【DP+二分】
      • LeetCode--309. 买卖股票的最佳时机含冷冻期
      • LeetCode--31. 下一个排列
      • LeetCode--3186. 施咒的最大总伤害
      • LeetCode--32. 最长有效括号【栈和dp】
      • LeetCode--322. 零钱兑换
      • LeetCode--328. 奇偶链表
      • LeetCode--329. 矩阵中的最长递增路径
      • LeetCode--33. 搜索旋转排序数组【直接二分】
      • LeetCode--337. 打家劫舍 III
      • LeetCode--3393. 统计异或值为给定值的路径数目
      • LeetCode--34. 在排序数组中查找元素的第一个和最后一个位置
      • LeetCode--3418. 机器人可以获得的最大金币数
      • LeetCode--343. 整数拆分
      • LeetCode--347. 前 K 个高频元素
      • LeetCode--347. 前 K 个高频元素Golang中的堆(containerheap)
      • LeetCode--354. 俄罗斯套娃信封问题
      • LeetCode--377. 组合总和 Ⅳ
      • LeetCode--39. 组合总和
      • LeetCode--394. 字符串解码【栈】
      • LeetCode--395. 至少有 K 个重复字符的最长子串
      • LeetCode--4. 寻找两个正序数组的中位数
      • LeetCode--40. 组合总和 II
      • LeetCode--402. 移掉 K 位数字
      • LeetCode--41. 缺失的第一个正数
      • LeetCode--415. 字符串相加
      • LeetCode--416. 分割等和子集_494. 目标和【01背包】
      • LeetCode--42. 接雨水(单调栈和双指针)
      • LeetCode--426. 将二叉搜索树转化为排序的双向链表
      • LeetCode--43. 字符串相乘
      • LeetCode--437. 路径总和 III【前缀和】
      • LeetCode--44. 通配符匹配
      • LeetCode--440. 字典序的第K小数字
      • LeetCode--442. 数组中重复的数据
      • LeetCode--445. 两数相加 II
      • LeetCode--45. 跳跃游戏 II
      • LeetCode--450. 删除二叉搜索树中的节点
      • LeetCode--46. 全排列
      • LeetCode--460. LFU 缓存
      • LeetCode--468. 验证IP地址
      • LeetCode--470. 用 Rand7() 实现 Rand10()
      • LeetCode--474. 一和零
      • LeetCode--48. 旋转图像
      • LeetCode--498. 对角线遍历
      • LeetCode--5. 最长回文子串
      • LeetCode--50. Pow(x, n)
      • LeetCode--509. 斐波那契数
      • LeetCode--516. 最长回文子序列
      • LeetCode--518. 零钱兑换 II
      • LeetCode--529. 扫雷游戏题解C++广搜
      • LeetCode--53. 最大子数组和
      • LeetCode--54. 螺旋矩阵
      • LeetCode--540. 有序数组中的单一元素
      • LeetCode--543. 二叉树的直径
      • LeetCode--55. 跳跃游戏
      • LeetCode--556. 下一个更大元素 III
      • LeetCode--56. 合并区间
      • LeetCode--560. 和为 K 的子数组
      • LeetCode--572. 另一棵树的子树
      • LeetCode--59. 螺旋矩阵 II
      • LeetCode--61. 旋转链表
      • LeetCode--62. 不同路径
      • LeetCode--622. 设计循环队列
      • LeetCode--63. 不同路径 II
      • LeetCode--64. 最小路径和
      • LeetCode--646. 最长数对链
      • LeetCode--662. 二叉树最大宽度
      • LeetCode--673. 最长递增子序列的个数
      • LeetCode--678. 有效的括号字符串
      • LeetCode--679. 24 点游戏
      • LeetCode--69. x 的平方根
      • LeetCode--695. 岛屿的最大面积
      • LeetCode--7. 整数反转
      • LeetCode--70. 爬楼梯
      • LeetCode--704. 二分查找
      • LeetCode--712. 两个字符串的最小ASCII删除和
      • LeetCode--714. 买卖股票的最佳时机含手续费
      • LeetCode--718. 最长重复子数组
      • LeetCode--72. 编辑距离
      • LeetCode--739. 每日温度
      • LeetCode--74. 搜索二维矩阵
      • LeetCode--740. 删除并获得点数
      • LeetCode--746. 使用最小花费爬楼梯
      • LeetCode--75. 颜色分类
      • LeetCode--76. 最小覆盖子串
      • LeetCode--77. 组合
      • LeetCode--78. 子集
      • LeetCode--79. 单词搜索
      • LeetCode--790. 多米诺和托米诺平铺
      • LeetCode--8. 字符串转换整数 (atoi)
      • LeetCode--82. 删除排序链表中的重复元素 II
      • LeetCode--83. 删除排序链表中的重复元素
      • LeetCode--84. 柱状图中最大的矩形【单调栈】
      • LeetCode--85. 最大矩形
      • LeetCode--87. 扰乱字符串
      • LeetCode--88. 合并两个有序数组
      • LeetCode--887. 鸡蛋掉落
      • LeetCode--91. 解码方法
      • LeetCode--912. 排序数组
      • LeetCode--918. 环形子数组的最大和
      • LeetCode--92. 反转链表 II
      • LeetCode--93. 复原 IP 地址
      • LeetCode--931. 下降路径最小和
      • LeetCode--94. 二叉树的中序遍历
      • LeetCode--958. 二叉树的完全性检验
      • LeetCode--97. 交错字符串
      • LeetCode--98. 验证二叉搜索树
      • LeetCode--983. 最低票价
      • LeetCode--LCR 140. 训练计划 II
      • NC--311.圆环回原点
      • NC--36进制加法
      • 补充题1. 排序奇升偶降链表
    • Redis
      • Redis基础部分
      • 在用Docker配置Redis哨兵节点的时候出现的错误及其解决
    • SQL学习记录
      • SQL碎片知识
      • 系统
        • MySQL学习笔记1【DQL和DCL】
        • MySQL学习笔记2【函数/约束/多表查询】
        • MySQL学习笔记3【事务】
        • MySQL学习笔记4【存储引擎和索引】
        • MySQL学习笔记5【SQL优化/视图/存储过程/触发器】
        • MySQL学习笔记6【锁】
        • MySQL学习笔记7【InnoDB】
    • x86汇编
      • 学习汇编随手记
    • 微服务相关
      • Nacos与gRPC
      • 【Golangnacos】nacos配置的增删查改,以及服务注册的golang实例及分析
    • 手搓
      • Whalebox(仿Docker)的爆诞
    • 操作系统
      • MIT6.S081-lab1
      • MIT6.S081-lab2
      • MIT6.S081-lab3
      • MIT6.S081-lab3前置
      • MIT6.S081-lab4
      • MIT6.S081-lab4前置
      • MIT6.S081-lab5
      • MIT6.S081-lab5前置
      • MIT6.S081-lab7
      • MIT6.S081-lab7前置
      • MIT6.S081-lab8
      • MIT6.S081-lab8前置
      • MIT6.S081-lab9
      • MIT6.S081-环境搭建
    • 消息队列MQ
      • Kafka
    • 算法杂谈
      • 关于二分查找时的边界分类问题
    • 计组笔记
      • 计算机组成原理的学习笔记(1)--概述
      • 计算机组成原理的学习笔记(10)--CPU·其二 组合逻辑控制器和微程序
      • 计算机组成原理的学习笔记(11)--CPU·其三 中断和异常多处理器相关概念
      • 计算机组成原理的学习笔记(12)--总线和IO系统
      • 计算机组成原理的学习笔记(2)--数据的表示和运算·其一
      • 计算机组成原理的学习笔记(3)--数据表示与运算·其二 逻辑门和加减乘
      • 计算机组成原理的学习笔记(4)--数据的表示与运算·其三 补码的乘法以及原码补码的除法
      • 计算机组成原理的学习笔记(4)--数据的表示与运算·其三 补码的乘法以及原码补码的除法
      • 计算机组成原理的学习笔记(6)--存储器·其一 SRAMDRAMROM主存储器的初步认识
      • 计算机组成原理的学习笔记(7)--存储器·其二 容量扩展多模块存储系统外存Cache虚拟存储器
      • 计算机组成原理的学习笔记(8)--指令系统·其一 指令的组成以及数据寻址方式RISK和CISK
      • 计算机组成原理的学习笔记(9)--CPU·其一 CPU的基本概念流水线技术数据通路
    • 闲聊
      • 2025-03-23记
      • 大一上总结
由 GitBook 提供支持
在本页
  • 1. 架构
  • 1.1 内存部分
  • 1.2 磁盘部分
  • 1.3 后台线程
  • 2. 事务原理
  • 2.1 事务
  • 2.2 redo log
  • 2.3 undo log
  • 3. MVCC(多版本并发控制)
  • 3.1 当前读
  • 3.2 快照读
  • 3.3 MVCC
  1. Note
  2. SQL学习记录
  3. 系统

MySQL学习笔记7【InnoDB】

1. 架构

1.1 内存部分

buffer pool

缓冲池是主存中的第一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删查改操作时,先操作缓冲池中的数据,然后以一定频率刷新到磁盘,这样操作明显提升了速度。

缓冲池以page为单位,底层采取链表的数据结构管理page,这一点和xv6是一模一样的,根据状态,分为三类:

  • 空闲页free page

  • 干净页clean page,分配之后没有被修改过

  • 脏页dirty page,数据被修改过,与磁盘中的数据不一致

change buffer

更改缓冲区,字面意思,主要针对于二级索引页,当我们在buffer pool执行数据变更操作(DML)的时候,如果没有找到这个数据,并不会直接读取磁盘数据,而是将其写入到change buffer,等未来读取数据的时候,直接将数据合并,恢复到buffer pool中,再将数据刷新到磁盘中,由于二级索引页插入删除相对随机,所以如果每次写入都会进行磁盘IO的话,性能太差,而使用change buffer,就减少了磁盘IO,提高了读写效率。

自适应哈希

自适应哈希索引,我们的InnoDB引擎默认是B+树索引,相对于哈希表慢一点,但是哈希表不支持范围查询,所以InnoDB为了提高查询效率,为buffer pool添加了一个自适应哈希索引,我们的InnoDB引擎会自己监控各个索引页上的索引,如果观察到hash索引可以提升查询速度,就会建立哈希索引,这个过程无需人工干预,但是我们需要知道这个参数是adaptive_hash_index,默认开启。

log buffer

保存要写入到磁盘中的两份日志:redo log和undo log,默认大小16M,会定期刷新到磁盘,如果更新插入较频繁,增加缓冲区大小可以减少磁盘IO,参数:

  • innodb_log_buffer:缓冲区大小。

  • innodb_flush_log_trx_commit:刷新到磁盘的时机。

    • 1:每次事务提交写入

    • 0:每秒写入

    • 2:两者结合


1.2 磁盘部分

系统表空间

主要处理非主键非唯一的二级索引的更改缓冲区,也就是change buffer,当然,这个和内存中的change buffer不一样,它主要用来存储我们的在真正写入表空间的变更操作,为啥不直接写入表空间?,原因是这样可以进一步避免频繁的磁盘IO,我们缓存的是变更操作,而不是整页的数据,并且在磁盘上,可以缓存大量变更。

文件表空间

我们建立的每一张表都有一个独立的表空间,文件表空间都包含单个InnoDB表的结构,数据和索引,并且存储在文件系统的单个数据文件中,参数:innodb_file_per_table。

通用表空间

如果我们没有自己去创建,是没有这个通用表空间的,需要通过CREATE TABLESPACE来创建,我们可以为表指定表空间

CREATE TABLE [name] (
	...
    ...
)TABLESPACE [spacename];

这样可以使得多个表共享一个ibd文件,避免ibd文件过多,当然,这些表依旧是独立的,我们可以将许多小型的表集中存储,可以减少磁盘碎片,简化管理,并且利于批量的备份恢复。

撤销表空间

在mysql实例初始化时会自动创建两个默认的undo表空间,初始大小16M,用于存储undo log日志,保证事务的原子性和一致性,主要用于支持事务的回滚操作。

临时表空间

用于存储用户创建的临时表,比如说多表查询时会创建一个临时表,我们在执行查询/排序/GROUP BY等等的复杂操作时,可能会产生一个临时表存储中间结果,而这个临时表就存储在临时表空间当中,查询结束后,就会自动清理。

双写缓冲区

InnoDB引擎将数据页从buffer pool刷新到磁盘前,先会将数据页写入到双写缓冲区文件,便于系统异常时恢复。

重做日志

redo log,用来实现事务的持久性,由重做日志缓冲区和重做日志文件两部分组成,前者位于内存,后者位于磁盘,当事务提交之后,会将所有修改信息都存到该日志中,用于在刷新脏页到磁盘发生错误时的数据恢复使用。

而我们的redo log是一个循环写的机制,这一点和redis的AOF很像。

1.3 后台线程

将内存中缓存池的数据在合适的时机刷新入磁盘中。

Master Thread

核心后台线程,负责调度其他线程,还负责将缓冲池中的数据异步刷新到磁盘中,保持数据一致性,包括脏页的刷新,合并插入缓存,undo页的回收等。

IO Thread

在innodb引擎中,采取了AIO,也就是异步非阻塞IO,极大地提高了数据库的性能,我们的IO Thread主要负责这些异步请求的回调。

  • Read Thread:读操作

  • Write Thread:写操作

  • Log Thread:将日志缓冲区刷新到磁盘

  • Insert Buffer Thread:将写缓冲区的数据刷新到磁盘

Purge Thread

回收事务已经提交的Undo Log,事务提交之后,之前记录的undo log不再使用,就用purge thread来回收

Page Cleaner Thread

协助Master Thread刷新脏页到磁盘的线程,减轻核心后台线程的压力。


2. 事务原理

2.1 事务

前文我们知道,事务是密不可分的集合,具有ACID的特性,原子性,一致性,隔离性,持久性。

其中,原子性,一致性和持久性是由我们的redo log和undo log支持实现的;而隔离性是由我们InnoDB的锁机制和MVCC(多版本并发控制)实现的。

2.2 redo log

重做日志,记录事务提交时的数据页的修改,用来实现持久性,由redo log buffer和redo log file两部分组成,前者内存,厚泽磁盘,事务提交之后,会把所有修改信息都存到该日志文件中,用于刷新脏页到磁盘,发生错误时进行数据恢复使用,大致流程如下:

  1. 客户端向mysql服务端发起update操作

  2. mysql查询buffer pool,发现没有我们需要更新的数据。

  3. 启动后台线程,从后台读取我们需要的信息,随后写入到缓冲区,此时就可以直接对缓冲区进行操作,并且会将增删改的数据写入到redo log buffer当中,此时磁盘和内存数据不一致,称之为脏页。

  4. 那么我们如果定期将内存的数据刷新到磁盘,此时出错了,如果没有redo log buffer,我们的事务已经提交,说明了无法得到数据持久性保证,但是我们有了redo log,我们的redo log buffer会直接将修改的数据刷新到磁盘中的redo log file,如果出错了,就会通过redo log file恢复数据,**为啥redo log buffer不直接刷新到真正的数据页?**因为我们真正的数据页刷新将会是随机的IO,而直接记录到日志上是顺序写,所以性能更高。

  5. 而我们的redo log日志是类似循环写的模式,每隔一段时间都会被清理。

2.3 undo log

undo log日志解决原子性问题,叫做回滚日志,记录数据被修改前的操作,它可以提供回滚和MVCC(多版本并发控制),undo log和redo log的记录物理日志不一样,他是逻辑日志,比如说我们insert一条信息,在undo log中就是delete的形式记录,当我们执行rollback,就可以读取到相应的内容进行回滚。

undo log在事务执行时产生,但是在事务提交时并不会立刻删除,因为这些日志还可能用于MVCC,并且undo log采取段的方式时机管理和记录,存在rollback段,内部包含1024个undo log。


3. MVCC(多版本并发控制)

3.1 当前读

读取的是记录最新版本的记录,会加锁保证其他并发事务不会修改,我们在事务隔离级别可重复读中使用事务,如果在进入事务之后,有数据被修改,那么我们读取到的数据并不是最新的,也就不是当前读,如果想要当前读,我们可以执行 SELECT ... LOCK IN SHARE MODE ,初次之外,还可以使用 SELECT FOR UPDATE/INSERT/DELETE 来实现当前读。

3.2 快照读

简单的selete就是我们的快照读,比如我们在可重复读的事务隔离级别中,就是典型的快照读,不加锁,是非阻塞读,当然,在我们的串行化的事务隔离级别中,快照读就会退化为当前读,在read committed中,每次select都会生成一个快照读。

3.3 MVCC

多版本并发控制,它会维护一个数据的多个版本,使得读写操作没有冲突,快照读为mysql实现mvcc提供了一个重要的非阻塞读功能,当,MVCC还依赖于数据库记录的三个隐式字段,undo log, readview。

隐式字段

当我们创建表的时候,会指定相应的表结构,包括id,name,age的字段,我们可以显式的看到这些字段,但是实际上,mysql还未我们隐藏了三个额外增加的字段:

DB_TRX_ID:最近修改事务ID,记录最后插入或修改这一行的事务ID。

DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本,配合undo log。

DB_ROW_ID:隐藏主键,如果表结构没有主键,就会生成这个隐藏字段。

undo log

我们之前提过,undo log在一定情况下不会被立即删除,比如update和delete,产生的undo log不仅在回滚时需要,快照读的时候也需要,所以不会被立即删除,而insert只会在回滚的时候才需要,所以在事务提交的时候可以立即删除,下面来看看实例分析:

借用一下黑马程序员的图

以上的示例列举的进行修改操作时的MVCC的版本链的控制,而执行查询操作的时候,则涉及到了另一个组件readView

readview

读视图,是快照读SQL执行时MVCC提取数据的依据,记录并维护当前活跃的事务(未提交)的id,包含四个核心字段:

m_ids:当前活跃的事务ID的集合

min_trx_id:最小的活跃事务ID

max_trx_id:预分配事务ID,当前最大事务ID + 1

creator_trx_id:readview创建者的事务ID

版本链访问规则:

trx_id(当前事务ID) == creator_trx_id:ok,说明数据是当前事务更改的。

trx_id < min_trx_id:ok,说明数据已经提交。

trx_id > max_trx_id:no,该事务是在readview生成后才开启的。

min_trx_id <= trx_id <= max_trx_id && trx_id 不存在于m_ids中:ok,数据已经提交。

readview生成时机在不同隔离级别有所不同:

read committed:事务每次执行快照读时,都会生成。(这里建议去看看黑马的视频里面的分析)

repeatable read:在事务第一次执行快照读时生成readview,后续复用这个readview。

这样,原理就介绍完毕了。

上一页MySQL学习笔记6【锁】下一页x86汇编

最后更新于1天前

QQ_1744376486010