MySQL数据落盘原理(redo、undo、binlog、2PC、double write等。)

news2024/11/20 3:31:59

文章目录

  • 前言
  • 一、架构图
      • 1、MySQL架构图
      • 2、InnoDB架构图
  • 二、落盘分析
      • 1.第一阶段
      • 2.第二阶段
      • 3.第三阶段
      • 4.第四阶段
      • 5.第五阶段
      • 6.第六阶段


前言

在上一章中我们聊到了事务有四大特性:原子性、一致性、隔离性、持久性。本篇文章就持久性重点聊一下,在高性能MySql一书中,对持久性的定义是:一旦事务提交,则起所做的修改就会永久保存到数据库中,此时即使数据库或系统崩溃,修改的数据也不会丢失。
持久性这个概念有点模糊,因为实际上持久性也是分很多种不同的级别的,有些持久性策略能够提供很强的安全保障,有些则未必,并且不可能有能做到100%安全保障的持久性策略,下面我们逐步展开MySQL种事务持久性的真正含义。

ps:基于innodb存储引擎


一、架构图

首先通过几张图片宏观上了解MySQL和innodb的架构

1、MySQL架构图

mysql

2、InnoDB架构图

通过以下两张innodb的架构图可以一目了然的看到innodb数据落盘过程
InnoDB架构图 innodb存储结构图

二、落盘分析

本节是将MySQL落盘过程由浅到深,由简单到复杂逐步分析,来达到理解落盘过程的目的。
落盘1
落盘2

1.第一阶段

假设此时MySQL修改数据后直接写入磁盘,就会有一个问题,数据写入磁盘时随机写的,性能极差,于是有了第二阶段。

2.第二阶段

此阶段增加了缓存这一步,即MySQL修改数据后保存在缓存中,然后由后台线程异步写入磁盘,这个过程也有一个明显的问题,当数据还在缓存中尚未写入磁盘时系统崩溃,会导致数据丢失,安全级别相当差,于是有了第三阶段。

3.第三阶段

此阶段增加了redo log,即更新缓存后,并且同步将redo log写入磁盘,由于redo log是顺序写词盘,所以效率也并不低。这时遇到数据还在缓存中尚未写入磁盘时系统崩溃的情况,MySQL重启是可以根据redo log的内容进行落盘。
但是此时会有脏读,不可重复读等问题,破坏了事务的隔离性。比如A事务更新了缓存但事务尚未提交,B事务去读就会读取到A事务的更新。
这个时候可能有人问了,那A事务更新的时候锁定数据不让B事务读可以吗?可以是可以,但是会导致读性能太差。于是有了第四阶段。

4.第四阶段

此阶段增加了undo log,即在更新缓存前先把对应的反向逻辑日志写到undo log buffer,这样B事务读取事务读取历史版本即可(MVCC机制)。
但是仔细一想还是有问题,那就是MySQL数据落盘是以页为单位的,其大小是16KB,而操作系统的页大小是4KB,如果在落盘的时候操作系统写了12KB时崩溃了,咋办?还有4KB数据呢(这种情况被称为部分写失效),这种情况下MySQL重启如何恢复??
可能有些同学会想通过redo log来恢复,这是不行的,因为redo log记录的是对页的物理操作,如偏移量800,写’aaa’记录,所以redo log生效的前提必须是MySQL数据页是完整的(姜承尧.MySQL技术内幕:InnoDB存储引擎)。
此时在MySQL崩溃重启恢复应用redo log前,需要一个页的副本,当发生部分写失效时,先通过该页的副本来还原该页后再应用redo log,这里所谓的页副本,这种策略就是double write。于是有了第五阶段。

PS:关于undo log落盘
用户定义的临时表的 undo log不刷盘,非临时表的undo log要刷盘的,undo log记录了事务修改前逻辑日志,本质上是数据,和正常表区别不大,它的内容除了记录到undo tablespaces,也会被记录到redo log。其中刷盘到undo tablespaces的机制和正常表数据一致(异步刷盘),刷盘到redo log的机制是和该undo log其对应的redo log一起刷盘的。

5.第五阶段

此阶段增加了double write buffer,先将缓存中的数据搬到该缓冲区,再刷到共享表空间和各个独立表空间,细节如下:

double write由两部分组成,一部分是内存中的double write buffer,大小为2MB,另一部分是物理磁盘上共享表空间中连续的128个页,即2个区(extent),大小同样为2MB。在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存中的double write buffer,之后通过double write buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题。在这个过程中,因为double write页是连续的,因此这个过程是顺序写的,开销并不是很大。在完成double write页的写入后,再将double write buffer中的页写入各个表空间文件中,此时的写入则是随机的,开销大。

这样就完美解决了 部分写失效 问题,即使写共享表空间失败,因为还没有写独立表空间,此时直接通过redo log恢复即可,如果写共享表空间成功,写独立表空间部分失败,先通过共享表空间的副本页恢复,再通过redo log恢复。

6.第六阶段

我们知道,在实际项目中,MySQL很少单节点,一般至少主从,双主等,此时必须开启binlog用于主从同步,那么binlog与redo log落盘关系如何呢?
如图所示,此时引入了XA分布式协议,保证binlog和redo log提交顺序。

  • prepare 阶段
    redo log落盘,此时redo log是prepare标志
  • commit 阶段
    binlog落盘,此时把redo log标志又prepare变更为commit,表示redo log完整提交。

在MySQL崩溃恢复时,为了保证主从数据一致,检测到binlog完整(redo log至少prepare了),此时提交数据,如果binlog不完整或没有,则回滚数据,回滚用的redo log中的undo log的redo log(太绕了,好好梳理下)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

离子交换法处理含铬废水

含铬废水是从哪里来的? 含铬废水来自:冶金、化工、矿物工程、电镀、制铬、颜料、制药、轻工纺织、铬盐及铬化物的生产等一系列行业,都会产生大量的含铬废水。 含铬废水危害有多大? 1、铬化合物具有致癌作用; 2、铬…

做SSM项目的步骤和优化

SSM框架整合 这里说的SSM整合,主要说的是Spring和mybatis之间的整合。因为spring和springMVC都是spring生态系统中的框架,所以spring和springMVC之间的整合是无缝的整合,即,我们在不知不觉中,其实spring和springMVC已…

【C++】list的使用

文章目录 1. list的使用1. 构造函数2.迭代器的使用和数据访问3. 容量相关4. 数据修改1.数据插入2. 数据删除 5.其他接口 1. list的使用 首先,在使用list之前,我们得先了解list到底是个什么东西,查看文档可以了解到,list的底层是一…

使用EasyExcel导出模板并设置级联下拉及其原理分析

一、概述 项目中有时会遇到需要导出一个Excel模板,然后在导出的Excel中填充数据,最终再调用接口批量把Excel中的数据导入到数据库当中的需求。 其中级联下拉选择,手机号校验,性别校验等都是比较常见的校验。 这里就已上面三种情…

县级医院手术麻醉管理系统源码 医院手麻系统源码 C/S架构 系统成熟稳定完整二次开发

医院手麻系统详细功能介绍和说明: ▶手术管理功能包括:手术申请、手术安排、查看手术申请单、手术通知单、填写病人术前会诊记录、谈话记录、麻醉记录、手术记录、附加手术、术后信息及手术回顾等功能。 ▶手术麻醉管理系统包括:手术申请、…

openEuler 欧拉 安装Oracle19c数据库RPM包安装

一、准备工作 将安装部署包上传到服务器上,我安装包放到/home目录下 二、安装依赖包 yum -y install binutils compat-libcap1 compat-libstdc-33 compat-libstdc-33*.i686 elfutils-libelf-devel gcc gcc-c glibc*.i686 glibc glibc-devel glibc-devel*.i686 ksh…

“烧钱”的大模型:初探成本拆解与推理优化方法

编者按:大模型的成本问题一直以来是大家重点关注的问题,本文重点讨论了训练大型语言模型(LLMs)需要的成本,并简要介绍什么是LLM以及一些用于优化大模型推理表现的技术。 虽然很难准确预测LLMs未来会怎么发展&#xff0…

热血

周五的晚上,决定去看「灌篮高手」电影了。 那还是很多年以前,樱木双手插进裤腰歪头扭嘴吹着口哨,那不羁的样子像极了一只从上往下看的沙雕。 而全国赛的樱木,多少是成熟了很多,是会说一些犯二的话,会和流川…

Spring Boot中上传文件不写临时文件

Spring Boot中上传文件不写临时文件 前言 在SpringBoot文件上传中,用MultipartFile类型接收文件时,SpringBoot会生成一份临时文件,文件格式为upload_*.tmp,如果业务场景有大量小文件需要上传的话,可以将文件直接丢到…

面试官:说说对称加密、非对称加密、混合加密?

对称加密 两边用同一个密钥来加解密。 A把明文通过某一算法加密之后得到密文,然后把密文发送给B,B接收到密文之后用相同的密钥执行相同的算法去解密。X没有密钥,即使窃取到密文也无法窃听。 对称加密的有优缺点 对称加密的优点&#xff1a…

TryHackMe-Misguided Ghosts(boot2root)

Misguided Ghosts 端口扫描 循例nmap FTP枚举 直接登anonymous,有几个文件,下下来 info.txt 我已经包含了您要求的所有网络信息,以及一些我最喜欢的笑话。- 帕拉摩尔该信息可能指的是pcapng文件 jokes.txt Taylor: Knock, knock. Josh: …

【pytest】

pytest 1、环境安装 1、pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple --targetC:\Dpan-app\ceshirenenv\Lib\site-packages 2、pycharm安装 2、assert >>> assert True >>> >>> assert False Traceback (most recent call …

一篇文章让你彻底学会--节流(并且自己可以手写)

Hi,有的小伙伴们在面试的时候会被要求手写节流函数,很多都被难着了吧,宝贝,那你你没有理解节流函数。 今天,就让我带你攻克它! 1.节流 单位时间内,事件触发,最多只执行一次事件回调。 人话:说…

【STL十三】适配器——迭代器适配器

【STL十二】适配器——迭代器适配器 一、迭代器1、迭代器分类2、迭代器定义3、迭代器和迭代器适配器 二、迭代器适配器、流迭代器1、简介2、迭代器适配器3、流迭代器 三、反向迭代器1、简介2、模板类3、demo 四、插入迭代器1、简介2、模板类3、demo 五、移动迭代器1、简介2、模…

Mysql列的类型定义(日期和时间类型)

文章目录 前言一、类型表二、类型简介总结 前言 日期与时间类型是为了方便在数据库中存储日期和时间而设计的,数据库有多种表示日期和时间的数据类型。其中,YEAR类型表示年,DATE类型表示日期,TIME类型表示时间,DATETIM…

大模型如何赋能?个人AI助理开始靠谱!

想象一下,生活在这样一个世界里,你有一个个人人工智能助手,它不仅能理解你的需求,还能与你一起学习和成长。一个人工智能无缝融入我们日常生活的世界,使我们能够比以往任何时候都更有效地实现我们的目标。那个世界不再…

Linux磁盘分区扩容

磁盘分区主要包含MBR(Master Boot Record)和GPT(GUID Partition Table)两种不同方式: MBR(主引导记录),驱动器上的一个特殊的启动扇区,最大支持2TB,最多支持4…

【Redis7】Redis7 主从复制(重点:主从复制原理)

【大家好,我是爱干饭的猿,本文重点介绍Redis7 复制。 后续会继续分享Redis7和其他重要知识点总结,如果喜欢这篇文章,点个赞👍,关注一下吧】 上一篇文章:《【Redis7】Redis7 事务&管道&…

navicat 远程连接oracle数据库ORA-12170及ORA-28547问题

目录 1.ORA-12170问题 2.ORA-28547 问题 1.ORA-12170问题 这是防火墙端口连接问题,需要在防火墙中设置oracle数据库端口为例外 解决方案 控制面板—windows防火墙—高级设置—入站规则—新建规则 2.ORA-28547 问题 OCI版本不兼容问题,安装的oracle客…

Python每日一练(20230423)

目录 1. 删除链表的倒数第 N 个结点 🌟🌟 2. 最小覆盖子串 🌟🌟🌟 3. 二叉树的层序遍历 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏…