MySQL里的两个“二次”

news2024/11/18 13:38:56

文章中所有图片均来自网络
一、double write
第一个二次是mysql一个崩溃恢复很重要的特性-重复写入。
doublewrite缓冲区是位于系统表空间中的存储区域,在该区域中,InnoDB会在将页面写入数据文件中的适当位置之前,从InnoDB缓冲池中刷新这些页面。仅在刷新页面并将其写入doublewrite缓冲区后,InnoDB才会将页面写入其适当位置。如果在页面写入过程中发生操作系统,存储子系统或mysqld进程崩溃,InnoDB稍后可以在崩溃恢复期间从doublewrite缓冲区中找到该页面的良好副本。
部分页面写
InnoDB的页面大小通常是16KB,其数据校验也是针对这16KB来计算的,将数据写入到磁盘并以页面为单位进行操作的。而计算机硬件和操作系统,在极端情况下(有时断电) )通常并不能保证这一步的原子性,16K的数据,写入4K时,发生了系统断电/ os崩溃,只有一部分写是成功的,这种情况下就是局部页面写问题。
很多DBA会想到系统恢复后,MySQL可以根据redolog进行恢复,而mysql在恢复的过程中是检查页面的校验和,checksum就是pgae的最后事务号,发生部分页面写问题,页面已经损坏,找不到该页面中的事务号,就无法恢复。
在这里插入图片描述

double write原理
Double write是InnoDB在表空间上的128个页(2个区)是2MB;
为了解决部分页写问题,当mysql将脏数据刷新到数据文件的时候,先使用内存复制将脏数据复制到内存中的double write buffer,之后通过double write buffer再分2次,每次写入1MB到共享表空间,然后立即调用fsync函数,同步到磁盘上,避免缓冲带来的问题,在这个过程中,doublewrite是顺序写,不会大小写大,在完成doublewrite写入后,在将double write buffer写入各个表空间文件,这时是离散写入。
如果发生了极端情况(断电),InnoDB再次启动后,发现了一个页面数据已经损坏,那么此时就可以从doublewrite buffer中进行数据恢复了。
图片来源网络
double对性能的影响
在共享表空间上的双重写缓冲区实际上也是一个文件,写DWB会导致系统有更多的fsync操作,而硬盘的fsync性能,所以它会降低mysql的整体性能。但是并不会降低到原来的50%。这主要是因为:
1)double write是一个连接的存储空间,所以硬盘在写数据的时候是顺序写,而不是随机写,这样性能更高。
2)将数据从双写缓冲区写入到真正的segment中的时候,系统会自动合并连接空间刷新的方式,每次可以刷新多个页面;
如果页面大小是16k,那么就有128个页面(1M)需要写,但是128个页面写入到共享表空间是1次IO完成,则doublewrite写入是1 + 128次。其中128次是写数据文件表空间。
doublewrite写入是顺序的,性能开销转化为量,通常5%-25%的性能影响。

double在恢复的时候是如何工作的?
如果部分页面写入doublewrite缓冲区本身,则原始页面仍将保留在磁盘上的实际位置。
如果是写双写缓冲区本身失败,那么这些数据不会被写入磁盘,InnoDB此时会从磁盘加载原始数据,然后通过InnoDB的事务日志来计算出正确的数据,重新写入到双写缓冲区。
当InnoDB恢复时,它将使用原始页面而不是doublewrite缓冲区中的损坏副本。但是,如果双写缓冲区成功并且对页面实际位置的写入失败,则InnoDB将在恢复期间使用双写缓冲区中的副本。
如果doublewrite buffer写成功的话,但是写磁盘失败,InnoDB就不用通过事务日志来计算了,或者直接用buffer的数据再写一遍。
InnoDB知道页面何时损坏,因为每个页面的末尾都有一个校验和。校验和是最后要写入的内容,因此,如果页面的内容与校验和不匹配,则页面已损坏。因此,恢复后,InnoDB只会读取doublewrite缓冲区中的每个页面并验证校验和。如果页面的校验和不正确,它将从其原始位置读取页面。
在恢复的时候,InnoDB直接比较页面的校验和,如果不对的话,就从硬盘加载原始数据,再由事务日志开始推演正确的数据。所以InnoDB的恢复通常需要花费时间。

重复写相关参数
InnoDB_doublewrite = 1表示启动双写,显示状态为’InnoDB_dblwr%‘可以查询双写的使用情况;
#是否开启double write
mysql>显示类似’%double%write%'的变量;
#Double write的使用情况
mysql>显示状态,例如“%InnoDB_dblwr%”;
InnoDB_dblwr_pages_write#从bp刷新到DBWB的个数
InnoDB_dblwr_writes#写文件的次数
每次写操作合并page的个数= InnoDB_dblwr_pages_write / InnoDB_dblwr_writes
在这里插入图片描述

图片源自wang’l

是否一定需要重复写
在某些情况下,确实没有必要使用doublewrite缓冲区-例如,您可能想在从属服务器上禁用它。另外,某些文件系统(例如ZFS)本身也会执行相同的操作,因此InnoDB这样做是多余的。您可以通过将InnoDB_doublewrite设置为0来禁用双写缓冲区。
1,Fursion-io原子写,如果每次写16k就是16k,每次写都是16k不会出现部分写partial write写4k的情况。
2,特定的文件系统(b-tree文件系统),支持原子写。
为了解决部分页写问题,当mysql将脏数据刷新到数据文件的时候,先使用内存复制将脏数据复制到内存中的doublewritebuffer,之后通过doublewritebuffer再分2次,每次写入1MB到共享…

二、两阶段提交
第二个两次就是两阶段提交
InnoDB引擎更新一条指定数据的过程如下:
在这里插入图片描述

可以看到,InnoDB在写redo log时,并不是一次性写完的,而有两个阶段,Prepare与Commit阶段,这就是"两阶段提交"的含义。

为什么要写redo log,不写redo log的话,根本就不会出现“两阶段提交”的麻烦事啊?
先说结论:在于崩溃恢复。

MySQL为了提升性能,引入了BufferPool缓冲池。查询数据时,先从BufferPool中查询,查询不到则从磁盘加载在BufferPool。

每次对数据的更新,也不总是实时刷新到磁盘,而是先同步到BufferPool中,涉及到的数据页就会变成脏页。同时会启动后台线程,异步地将脏页刷新到磁盘中,来完成BufferPool与磁盘的数据同步。如果在某个时间,MySQL突然崩溃,则内存中的BufferPool就会丢失,剩余未同步的数据就会直接消失。

虽然在更新BufferPool后,也写入了binlog中,但binlog并不具备crash-safe的能力。因为崩溃可能发生在写binlog后,刷脏前。在主从同步的情况下,从节点会拿到多出来的一条binlog。所以server层的binlog是不支持崩溃恢复的,只是支持误删数据恢复。InnoDB考虑到这一点,自己实现了redo log。

为什么写两次redo
为什么要写两次redo log,写一次不行吗?
redo log与binlog都写一次的话,也就是存在以下两种情况:
先写binlog,再写redo log:当前事务提交后,写入binlog成功,之后主节点崩溃。在主节点重启后,由于没有写入redo log,因此不会恢复该条数据。而从节点依据binlog在本地回放后,会相对于主节点多出来一条数据,从而产生主从不一致。
先写redo log,再写binlog:当前事务提交后,写入redo log成功,之后主节点崩溃。在主节点重启后,主节点利用redo log进行恢复,就会相对于从节点多出来一条数据,造成主从数据不一致。
因此,只写一次redo log与binlog,无法保证主节点崩溃恢复与从节点本地回放数据的一致性。

如何实现奔溃恢复
在两阶段提交的情况下,是怎么实现崩溃恢复的呢?
首先比较重要的一点是,在写入redo log时,会顺便记录XID,即当前事务id。在写入binlog时,也会写入XID。因此存在以下三种情况:

如果在写入redo log之前崩溃,那么此时redo log与binlog中都没有,是一致的情况,崩溃也无所谓。
如果在写入redo log prepare阶段后立马崩溃,之后会在崩恢复时,由于redo log没有被标记为commit。于是拿着redo log中的XID去bin log中查找,此时肯定是找不到的,那么执行回滚操作。
如果在写入bin log后立马崩溃,在恢复时,由redo log中的XID可以找到对应的bin log,这个时候直接提交即可。
总的来说,在崩溃恢复后,只要redo log不是处于commit阶段,那么就拿着redo log中的XID去binlog中寻找,找得到就提交,否则就回滚。在这样的机制下,两阶段提交能在崩溃恢复时,能够对提交中断的事务进行补偿,来确保redo log与binlog的数据一致性。

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

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

相关文章

海量物理刚体 高性能物理引擎Unity Physics和Havok Physics的简单性能对比

之前的博客中我们为了绕过ECS架构,相当于单独用Batch Renderer Group实现了一个精简版的Entities Graphics,又使用Jobs版RVO2实现了10w人同屏避障移动。 万人同屏对抗割草 性能测试 PC 手机端 性能表现 弹幕游戏 海量单位同屏渲染 锁敌 避障 非ECS 那么有…

dolphinscheduler海豚调度(三)SQL任务

在之前的博文中,我们已经介绍了DolphinScheduler海豚调度的基本概念和模块,安装部署和元数据切换,以及Shell任务的实践。今天,让我们来深入探讨DolphinScheduler中另一种常见的任务类型:SQL任务。 SQL任务是DolphinSc…

嵌入式学习 Day 26

数组指针和指针数组 (题外话) 数组指针:数组指针是一种指针,它指向一个数组的首地址。在C语言中,数组名本身就是一个指向数组首地址的指针,因此数组名可以被赋值给指针变量&#xff0c…

07 Qt自绘组件:图片预览小组件ImageViewer

系列文章目录 01 Qt自定义风格控件的基本原则-CSDN博客 02 从QLabel聊起:自定义控件扩展-图片控件-CSDN博客 03 从QLabel聊起:自定义控件扩展-文本控件-CSDN博客 04 自定义Button组件:令人抓狂的QToolButton文本图标居中问题-CSDN博客 0…

使用Jenkins部署前端Vue项目和后端Java服务

Jenkins安装相关插件,供后续使用(Dashboard - Manage Jenkins - Plugins) Maven Integration plugin https://plugins.jenkins.io/maven-plugin CloudBees Docker Build and Publish pluginhttps://plugins.jenkins.io/docker-build-publish…

Unity中的UI系统之GUI

目录 概述工作原理和主要作用基础控件重要参数及文本和按钮多选框和单选框输入框和拖动条图片绘制和框 复合控件工具栏和选择网络滚动视图和分组窗口 自定义整体样式自定义皮肤样式 概述 什么是UI系统 UI是User Interface(用户界面)的简称,用…

【pytorch】函数记录

你好你好! 以下内容仅为当前认识,可能有不足之处,欢迎讨论! 文章目录 torch.sum()torch.argmax()torch.nn.Parametertorch.unbindtorch.optim.Adam()[^adam]torch.cattorch.unsqueeze()torch.normalize()[^l2]torch.eyetorch.mmto…

网站https证书申请方式

网站HTTPS证书,也称为SSL证书或TLS证书,是一种数字证书,用于在用户浏览器与网站服务器之间建立安全的加密连接。当网站安装了HTTPS证书后,用户访问该网站时,浏览器地址栏会显示为"https://"开头,…

NoSQL--虚拟机网络配置

目录 1.初识NoSQL 1.1 NoSQL之虚拟机网络配置 1.1.1 首先,导入预先配置好的NoSQL版本到VMware Workstation中 1.1.2 开启虚拟机操作: 1.1.2.1 点击开启虚拟机: 1.1.2.2 默认选择回车CentOS Linux(3.10.0-1127.e17.x86_64) 7 …

微服务架构 SpringCloud

单体应用架构 将项目所有模块(功能)打成jar或者war,然后部署一个进程--医院挂号系统; > 优点: > 1:部署简单:由于是完整的结构体,可以直接部署在一个服务器上即可。 > 2:技术单一:项目不需要复杂的技术栈,往往一套熟悉的…

STM32标准库开发—硬件SPI外设

SPI外设简介 SPI1与SPI2所挂载的总线位置不一样,所以时钟频率也不一样,SPI2挂载在APB1时钟频率为36MHZ是SPI1的一半 I2S是一种音频传输协议,适用于STM32大容量产品 一般来说串口发送数据时是低位先行,SPI通信是高位先行 SPI框图 发…

173基于matlab的经典STAP处理机载雷达信号

基于matlab的经典STAP处理机载雷达信号,空时自适应信号处理的典型算法、滤波器和相关参数的仿真,程序已调通,可直接运行。 173 matlab 空时自适应信号处理 STAR (xiaohongshu.com)https://www.xiaohongshu.com/explore/65d9cf11000000000102b…

谷歌seo推广好还是竞价排名好?

事实上seo跟sem竞价并没有任何冲突,也并没有哪个更好的说法,关键在于理解它们各自的优势与局限性,并根据你的业务,预算来配合 Seo推广的优势在于成本,只要你的网站在搜索结果获得高排名,就能有源源不断的点…

GaN建模:强大但富有挑战性

来源:Modeling GaN: Powerful but Challenging(10年) 文章的研究内容 这篇文章主要研究了氮化镓(GaN)高电子迁移率晶体管(HEMTs)的建模问题。GaN HEMTs是微波频段高功率发射器设计中的关键技术…

azure devops工具实践分析

对azure devops此工具的功能深挖,结合jira的使用经验的分析 1、在backlog的功能描述,可理解为需求项,这里包括了bug,从开发的角度修复bug也是个工作项,所以需求的范围是真正的需求(开发接收到的已经确认的…

【Kubernetes】k8s中容器之间、pod之间如何进行网络通信?

目录 PodKubernetes 网络模型同一Pod上的容器之间进行通信同一Node上的不同Pod之间进行通信不同Node上的Pod之间进行通信Service参考 Pod 首先来回顾一下Pod: Pod 是用于构建应用程序的最小可部署对象。单个 Pod 代表集群中正在运行的工作负载,并封装一…

Spring 事务传播机制

事务传播机制:多个事务⽅法存在调⽤关系时, 事务是如何在这些⽅法间进⾏传播的。 ⽐如:有两个⽅法A,B都被 Transactional 修饰,,A⽅法调⽤B⽅法 A⽅法运⾏时, 会开启⼀个事务。当A调⽤B时, B⽅法本⾝也有事务&#xf…

Golang Base64 编码:Go语言编码全面指南

在编码和解码数据的领域中,Base64作为一种广泛使用的方案脱颖而出,它提供了二进制数据的紧凑表示形式。Golang凭借其强大的标准库,提供了一种无缝且高效的方式来执行Base64编码。在这篇博客文章中,我们将通过Golang的Base64编码能…

mysql修改字段的长度锁表问题

mysql修改字段的长度锁表问题 背景 MySQL(这里指5.6及其后续版本)修改字段的长度锁表会锁表吗?答案是可能会但不一定会 具体原理 MySQL 5.6 及以后版本扩大字段长度 支持 online ddl in-place 模式,而这将不会锁表。varchar 表示…

链表之“带头双向循环链表”

目录 ​编辑 1.链表的分类 2.带头双向循环链表的实现 1.创建结构体 2.创建返回链表的头节点 3.双向链表销毁 4.双向链表打印 5.双向链表尾插 6.双向链表尾删 7.双向链表头插 8.双向链表头删 9.双向链表查找 10.双向链表在pos的前面进行插入 11.双向链表删除pos位…