MySQL是如何数据库事务特性之持久性的?

什么是事务的持久性?

当现实世界的一个状态转换完成后,这个转换的结果将永久的保留,这就称为持久性。

MySQL是如何实现事务的持久性?

我知道你很急,所以先把结论亮出来

具体的手段就是通过redo日志来实现。

下边的文字想看就看,不看也没关系啦~ 每条redo日志的结构差不多记载了发生变更的数据在哪儿(哪个表空间、哪个页号,哪个字节处开始),做了哪些变更。由于日志直接就指向了发生变更的物理地址,所以redo log其实也是个物理日志。


我知道你很急,但是你先别急,不如先看看现在是个什么情况?

请允许我图文介绍下现在的情况

可以看到途中有三个箭头连线,我们看上面两个。

当用户读写数据时,直接访问到的数据其实是内存中的数据,更准确得说,是一块叫做Buffer Pool的内存,而Buffer Pool的数据又来自磁盘。

图中可以看到数据页,其实可以叫页。所谓页,就是一个大小为16kb的内存空间。

我们的内存空间有限,总不能把所有磁盘数据加载到内存里吧,这么整地球都得爆炸!那只加载部分数据,也不能没个章法,所以定义一个"页"的概念,磁盘中的数据就可以被切分成好多页,每页16kb,然后再以页为最小单位,加载若干页到内存,这样数据库的各种管理是不是就很方便了,几乎很多操作就是以页为单位在进行的。

那么问题来了......

既然数据的源头是磁盘,为什么不直接访问磁盘?因为磁盘I/O实在不给力------慢死你,所以MySQL的设计中专门向操作系统申请了一块内存,并起名为Buffer Pool。

在这样的前提之下,用户直接操作的必然内存中的数据,这样肯定不算完:因为我们还没把这些数据刷入磁盘,此时伸出邪恶的小手,轻轻给你把电源插头,你不得吱哇乱叫:数据全特喵没了!

日常反思,可以跳过哈!

所以啊有时候解决一个单一的问题是很简单的,但是当多个问题揉在一起,一个问题的解决方案可能会为另一个问题的解决设置障碍,所以多个问题各自解决方案的组合也很重要,因为不恰当的解决优先级和针对前置问题的不当解决方案,可能会让后续问题的解决陷入僵局。拆分问题,打开思路,回过头来再思考,不要走进死胡同,自勉自省!

那......试试立刻刷盘?

按照我朴素的直觉,我肯定要支招了:那还等什么,赶紧刷盘!嗨~这想法蠢蠢的,怪可爱的啊......为啥?因为I/O很慢,要是能赶紧得起来,也就不会有Buffer Pool的设计啦!

谁不夸她一句救世主:redo log

让我这破锣一样的脑袋想,我是想到下辈子也想不粗来,还好MySQL的大佬们各个身怀绝技,这点问题不在话下,大佬们引入了redo log,专治各种不服。

redo log见文知意

至于redo log这个词儿 ,可难不倒我这个英语六级、张嘴就哑火的chglish杰出用户嘛!这不就是重做日志?"望文生义"一下:就是系统崩溃后,我可以根据重做日志(redo log),把崩溃期间没刷盘的数据变更再做一遍,不就......超完美的好嘛!当然,redo log的功能确实也是如此,并不是我胡说八道哈------看来一个好的名字是可以让知识更加顺利地进入脑袋瓜里的!

客户端发起写操作后,redo log 是如何参与进去的?

上面的图罗列了当客户端发起写操作后,数据库的4个举动:

  1. 修改数据页

这个时候就产生了脏页了,脏页也就是用户操作后发生变更的数据页。

  1. 修改redo log block

就是增加重做日志啦,这个是我们讨论持久性的重点关注对象。至于block,咱们只要知道block的含义其实和"页"是一样的就行,其他不用深究。

  1. 将redo log刷入磁盘
  2. 将脏页刷回磁盘

redo log 刷盘必须一马当先

注意哟,这几个动作先后顺序很重要,尤其是step3和4,只有保证3在4之前执行,通过redo log做崩溃恢复时,数据才是一致和准确的。此话怎讲?我们来穷举下崩溃的场景:

  1. 如果redo log刷盘失败,脏页刷盘还没执行到,系统崩溃后重启,会根据redo log恢复,很显然是没问题的:数据相当于什么修改都没发生过。
  2. 如果redo log成功,之后某个时间点系统崩溃,导致脏页数据刷盘失败,那么系统重启后就可以根据redo log 把缺失的这部分数据差异给补上啦。

对了,上述4步不是在一个事务时间内完成的

  • 比如"3.将redo log刷入磁盘",触发redo log刷盘的情况有好几种,比如提交时刷盘,后台线程定时刷盘,另外,是否在提交事务时刷盘,由细分出一个数据库变量innodb_flush_log_at_trx_commit 进行控制,不过我们只要记住默认情况下,提交事务时就会将redo log刷入磁盘就行了,其他不用太关心,知道有这么个事儿就行了;具体内容可以参掘金小册
  • 此外"4.将脏页刷回磁盘"这一神圣的任务是单独交给一个后台线程做的,会定时地、根据一系列的规则将脏页刷盘;所以从上面两个栗子来看,这4步不一定是在一个事务期间发生的,不过,我们把时间拉长看,这四个步骤一定是按照这样的先后顺序发生的。 具体内容可以参掘金小册中的"刷新脏页到磁盘"一节

最后的碎碎念

其实说到这里,关于MySQL是如何通过redo log实现事务四大特性的持久性的,也已经写得差不多了,欢迎大家指正和建议!

本文知识点主要参考稀土掘金网站的《MySQL 是怎样运行的:从根儿上理解 MySQL》小册的第19、21、22章,好记性它不如烂笔头呀!

相关推荐
团儿.41 分钟前
解锁MySQL高可用新境界:深入探索MHA架构的无限魅力与实战部署
数据库·mysql·架构·mysql之mha架构
权^2 小时前
MySQL--聚合查询、联合查询、子查询、合并查询(上万字超详解!!!)
大数据·数据库·学习·mysql
万事大吉CC5 小时前
mysql单表查询·3
数据库·mysql
苹果醋311 小时前
大模型实战--FastChat一行代码实现部署和各个组件详解
java·运维·spring boot·mysql·nginx
计算机学姐14 小时前
基于SpringBoot+Vue的高校运动会管理系统
java·vue.js·spring boot·后端·mysql·intellij-idea·mybatis
-XWB-14 小时前
【MySQL】数据目录迁移
数据库·mysql
掘根15 小时前
【MySQL】Ubuntu环境下MySQL的安装与卸载
数据库·mysql·centos
知识分享小能手16 小时前
mysql学习教程,从入门到精通,SQL 修改表(ALTER TABLE 语句)(29)
大数据·开发语言·数据库·sql·学习·mysql·数据分析
fat house cat_16 小时前
mysql-索引笔记
数据库·mysql
He guolin17 小时前
【MySQL】数据库基础知识
数据库·mysql