当前位置: 首页 > news >正文

【MySQL】深入解析MySQL双写缓冲区

原创不易,注重版权。转载请注明原作者和原文链接

文章目录

    • 为什么需要Doublewrite Buffer
    • Doublewrite Buffer原理
    • Doublewrite Buffer和redo log
    • Doublewrite Buffer相关参数
    • 总结

在数据库系统的世界中,保障数据的完整性和稳定性是至关重要的任务。为了实现这一目标,MySQL内部使用了许多精巧而高效的机制。

InnoDB是MySQL中一种常用的事务性存储引擎,它具有很多优秀的特性。其中,Doublewrite Buffer是InnoDB的一个重要特性之一,本文将介绍Doublewrite Buffer的原理和应用,帮助读者深入理解其如何提高MySQL的数据可靠性并防止可能的数据损坏。

为什么需要Doublewrite Buffer

我们常见的服务器一般都是Linux操作系统,Linux文件系统页(OS Page)的大小默认是4KB。而MySQL的页(Page)大小默认是16KB。

可以使用如下命令查看MySQL的Page大小:

SHOW VARIABLES LIKE 'innodb_page_size';

一般情况下,其余程序因为需要跟操作系统交互,所以它们的页(Page)大小都为操作系统页大小的整数倍。比如,Oracle的Page大小为8KB。

MySQL程序是跑在Linux操作系统上的,理所当然要跟操作系统交互,所以MySQL中一页数据刷到磁盘,要写4个文件系统里的页。

如图所示:

需要注意的是,这个刷页的操作并非原子操作,比如我操作系统写到第二个页的时候,Linux机器断电了,这时候就会出现问题了。造成「页数据损坏」。并且这种页数据损坏靠 redo日志是无法修复的。

redo重做日志中记录的是对页的物理操作,而不是页面的全量记录,当发生「Partial Page Write(部分页写入)」问题时,出现问题的是未修改过的数据,此时redo日志无能为力。

Doublewrite Buffer的出现就是为了解决上面的这种情况,给InnoDB存储引擎提供了数据页的可靠性,虽然名字带了Buffer,但实际上Doublewrite Buffer是「内存+磁盘」的结构。

内存结构:Doublewrite Buffer内存结构由128个页(Page)构成,大小是2MB。

磁盘结构:Doublewrite Buffer磁盘结构在系统表空间上是128个页(2个区,extend1和extend2),大小是2MB。

Doublewrite Buffer的原理是,再把数据页写到数据文件之前,InnoDB先把它们写到一个叫「doublewrite buffer(双写缓冲区)」的共享表空间内,在写doublewrite buffer完成后,InnoDB才会把页写到数据文件适当的位置。

如果在写页的过程中发生意外崩溃,InnoDB会在doublewrite buffer中找到完好的page副本用于恢复。

Doublewrite Buffer原理

如上图所示,当有数据页要刷盘时:

  1. 页数据先通过memcpy函数拷贝至内存中的Doublewrite Buffer中。

  2. Doublewrite Buffer的内存里的数据页,会fsync刷到Doublewrite Buffer的磁盘上,分两次写入磁盘共享表空间中(连续存储,顺序写,性能很高),每次写1MB。

  3. Doublewrite Buffer的内存里的数据页,再刷到数据磁盘存储.ibd文件上(离散写)。

如果操作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,InnoDB存储引擎可以从共享表空间中的Double write中找到该页的一个副本,将其复制到表空间文件,再应用redo日志

所以在正常的情况下,MySQL写数据页时,会写两遍到磁盘上,第一遍是写到doublewrite buffer,第二遍是写到真正的数据文件中,这便是「Doublewrite」的由来。

我们可以通过如下命令来监控Doublewrite Buffer工作负载,该命令用于显示有关双写缓冲区(doublewrite buffer)的统计信息。‘%dblwr%’ 是一个通配符,匹配所有包含 ‘dblwr’ 的状态变量。

show global status like '%dblwr%';

这个命令可能会产生如下格式的输出:

+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Innodb_dblwr_writes    | 1000  |
| Innodb_dblwr_pages_written | 8000  |
+------------------------+-------+

Doublewrite Buffer和redo log

在MySQL的InnoDB存储引擎中,Redo log和Doublewrite Buffer共同工作以确保数据的持久性和恢复能力。

  1. 当有一个DML(如INSERT、UPDATE)操作发生时, InnoDB会首先将这个操作写入redo log(内存)。这些日志被称为未检查点(uncheckpointed)的redo日志。
  2. 然后,在修改内存中相应的数据页之前,需要将这些更改记录在磁盘上。但是直接把这些修改的页写到其真正的位置可能会因发生故障导致页部分更新,从而导致数据不一致。因此,InnoDB的做法是先将这些修改的页按顺序写入doublewrite buffer。这就是为什么叫做 “doublewrite” —— 数据实际上被写了两次,先在doublewrite buffer,然后在它们真正的位置。
  3. 一旦这些页被安全地写入doublewrite buffer,它们就可以按原始的顺序写回到文件系统中。即使这个过程在写回数据时发生故障,我们仍然可以从doublewrite buffer中恢复数据。
  4. 最后,当事务提交时,相关联的redo log会被写入磁盘。这样即使系统崩溃,redo log也可以用来重播(replay)事务并恢复数据库。

在系统恢复期间,InnoDB会检查doublewrite buffer,并尝试从中恢复损坏的数据页。如果doublewrite buffer中的数据是完整的,那么InnoDB就会用doublewrite buffer中的数据来更新损坏的页。否则,如果doublewrite buffer中的数据不完整,InnoDB也有可能丢弃buffer内容,重新执行那条redo log以尝试恢复数据。

所以,Redo log和Doublewrite Buffer的协作可以确保数据的完整性和持久性。如果在写入过程中发生故障,我们可以从doublewrite buffer中恢复数据,并通过redo log来进行事务的重播。

Doublewrite Buffer相关参数

以下是一些与Doublewrite Buffer相关的参数及其含义:

  • innodb_doublewrite: 这个参数用于启用或禁用双写缓冲区。设置为1时启用,设置为0时禁用, 默认值为1。
  • innodb_doublewrite_files: 这个参数定义了多少个双写文件被使用。默认值为2,有效范围从2到127。
  • innodb_doublewrite_dir: 这个参数指定了存储双写缓冲文件的目录的路径。默认为空字符串,表示将文件存储在数据目录中。
  • innodb_doublewrite_batch_size: 这个参数定义了每次批处理操作写入的字节数。默认值为0,表示InnoDB会选择最佳的批量大小。
  • innodb_doublewrite_pages:这个参数定义了每个双写文件包含多少页面。默认值为128。

总结

Doublewrite Buffer是InnoDB的一个重要特性,用于保证MySQL数据的可靠性和一致性。

它的实现原理是通过将要写入磁盘的数据先写入到Doublewrite Buffer中的内存缓存区域,然后再写入到磁盘的两个不同位置,来避免由于磁盘损坏等因素导致数据丢失或不一致的问题。

总的来说,Doublewrite Buffer对于改善数据库性能和数据完整性起着至关重要的作用。尽管其引入了一些开销,但在大多数情况下,这些成本都被其提供的安全性和可靠性所抵消。


感谢阅读,如果本篇文章有任何错误和建议,欢迎给我留言指正。

相关文章:

【MySQL】深入解析MySQL双写缓冲区

原创不易,注重版权。转载请注明原作者和原文链接 文章目录 为什么需要Doublewrite BufferDoublewrite Buffer原理Doublewrite Buffer和redo logDoublewrite Buffer相关参数总结 在数据库系统的世界中,保障数据的完整性和稳定性是至关重要的任务。为了实现…...

u-boot 编译与运行

文章目录 u-boot 编译与运行环境配置ubuntu 版本qemu 版本u-boot 版本(master)交叉工具链版本 u-boot 源码下载生成配置文件报错情况一报错情况2 u-boot 配置编译编译脚本编译报错解决编译日志编译产物 运行 u-boot 编译与运行 本文主要介绍 u-boot 编译…...

C++QT-day2

#include <bits/stdc.h>/*自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c;定义公有成员函数:初始化函数:void init(int w, int h)更改宽度的函数:set_w(int w)更改高度的函数:set_h(int h)输出该矩形的周长和面积函数:void sho…...

【Acwing187】导弹防御系统(LIS+剪枝+贪心+dfs+迭代加深)

题目描述 看本文需要准备的知识 1.最长上升子序列&#xff08;lis&#xff09;的算法思想和算法模板 2.acwing1010拦截导弹&#xff08;lis贪心&#xff09;题解 本题题解&#xff0c;需要知道这种贪心算法 3.简单了解dfs暴力搜索、剪枝、搜索树等概念 思路讲解 dfs求最…...

字节大佬带你五分钟掌握接口自动化测试框架

今天&#xff0c;我们来聊聊接口自动化测试是什么&#xff1f;如何开始&#xff1f;接口自动化测试框架怎么做&#xff1f; 自动化测试 自动化测试&#xff0c;这几年行业内的热词&#xff0c;也是测试人员进阶的必备技能&#xff0c;更是软件测试未来发展的趋势。 特别是在…...

上传文件夹里面的文件后,按树结构的table表格展示

1. 先处理最简单的 原始数据大概是这样: let fileArr [{progress: 100,status: 成功,type: 通号,webkitRelativePath: "六捷数据2023-05-04 163909/G163/Abis口详细信息_(G163)(380BL3544-0)(14984173988)(2018-01-24 174431.0740—2018-01-24 180347.9070).xls"…...

【error】root - Exception during pool initialization

报错提示&#xff1a;root - Exception during pool initialization. 错误原因&#xff1a; 配置数据库出错 我的错误配置&#xff1a; spring.datasource.urljdbc:mysql://localhost:3306/springboot?serverTimezoneGMT spring.datasource.nameroot spring.datasource.pass…...

【重拾C语言】九、再论函数(指针、数组、结构体作参数;函数值返回指针、结构体;作用域)

目录 前言 九、再论函数 9.1 参数 9.1.1 参数的传递规则 9.1.2 指针作参数 9.1.3 数组作参数 9.1.4 结构体作参数 a. 直接用结构体变量作函数参数 b. 用指向结构体变量的指针作函数参数 9.2 函数值 9.2.1 返回指针值 9.2.2 返回结构体值 a. 返回结构体值 b. 返回…...

Spring WebClient 基于响应式编程模型的HTTP客户端

一、简介 WebClient是一个非阻塞的、可扩展的、基于Reactive Streams规范的HTTP客户端。它提供了一种简洁的方式来进行HTTP请求&#xff0c;并且可以很好地与其他Spring组件集成。WebClient支持同步和异步操作&#xff0c;使得它非常适合用于构建响应式应用程序。 WebClient允…...

IP真人识别方法与代理IP检测技术

随着互联网的发展&#xff0c;IP地址在网络安全和数据分析中扮演着重要的角色。为了维护网络的安全性和识别真实用户&#xff0c;IP地址的真实性和来源成为了一个关键问题。 什么是IP真人识别&#xff1f; IP真人识别是一种技术&#xff0c;旨在确定IP地址背后的用户是否为真实…...

MySQL 面试知识脑图 初高级知识点

脑图下载地址&#xff1a;https://mm.edrawsoft.cn/mobile-share/index.html?uuid18b10870122586-src&share_type1 sql_mode 基本语法及校验规则 ONLY_FULL_GROUP_BY 对于GROUP BY聚合操作&#xff0c;如果在SELECT中的列&#xff0c;没有在GROUP BY中出现&#xff…...

【数据结构】二叉树的链式结构及实现

目录 1. 前置说明 2. 二叉树的遍历 2.1 前序、中序以及后序遍历 2.2 层序遍历 3. 节点个数及高度等 4. 二叉树的创建和销毁 1. 前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。由于现在大家对二叉树结构…...

OpenCV4(C++)—— 创建窗口滑动条来调参

文章目录 创建滑动条 —— createTrackbar 创建滑动条 —— createTrackbar createTrackbar是OpenCV中的一个函数&#xff0c;用于创建一个可调节的滑动条&#xff08;Trackbar&#xff09;&#xff0c;以便在图像处理过程中实时调整参数 int cv::createTrackbar(const String…...

深度学习基础知识 学习率调度器的用法解析

深度学习基础知识 学习率调度器的用法解析 1、自定义学习率调度器**&#xff1a;**torch.optim.lr_scheduler.LambdaLR2、正儿八经的模型搭建流程以及学习率调度器的使用设置 1、自定义学习率调度器**&#xff1a;**torch.optim.lr_scheduler.LambdaLR 实验代码&#xff1a; i…...

【JUC系列-12】深入理解PriorityQueue的底层原理和基本使用

JUC系列整体栏目 内容链接地址【一】深入理解JMM内存模型的底层实现原理https://zhenghuisheng.blog.csdn.net/article/details/132400429【二】深入理解CAS底层原理和基本使用https://blog.csdn.net/zhenghuishengq/article/details/132478786【三】熟练掌握Atomic原子系列基本…...

Paddle安装

Paddle安装参考 docs/tutorials/INSTALL_cn.md PaddlePaddle/PaddleDetection - Gitee.comhttps://gitee.com/paddlepaddle/PaddleDetection/blob/release/2.6/docs/tutorials/INSTALL_cn.md # 不指定版本安装paddle-gpu python -m pip install paddlepaddle-gpu# 测试安装 …...

配置XP虚拟机和Win 10宿主机互相ping通

文章目录 一、关闭虚机和宿主机的防火墙1、关闭虚拟机的防火墙1.1方式一1.2方式二 2、关闭宿主机的防火墙 二、设置XP和宿主机VMnet8的IP地址、网关和DNS1、获取VMWare的虚拟网络配置信息2、设置XP的VMnet8的IP地址、网关和DNS3、设置宿主机VMnet8的IP地址、网关和DNS 三、获取…...

【机器学习】sklearn对数据预处理

文章目录 数据处理步骤观察数据数据无量纲化缺失值处理处理分类型特征处理连续型特征 数据处理步骤 数据无量纲化缺失值处理处理分类型特征&#xff1a;编码与哑变量处理连续型特征&#xff1a;二值化与分段 观察数据 通过pandas读取数据&#xff0c;通过head和info方法大致查…...

【智慧燃气】智慧燃气解决方案总体概述--终端层、网络层

关键词&#xff1a;智慧燃气、智慧燃气系统、智慧燃气平台、智慧燃气解决方案、智慧燃气应用、智能燃气 智慧燃气解决方案是基于物联网、大数据、云计算、移动互联网等先进技术&#xff0c;结合燃气行业特征&#xff0c;通过智能设备全面感知企业生产、环境、状态等信息的全方…...

Tomcat隔离web原理和热加载热部署

Tomcat 如何打破双亲委派机制 Tomcat 的自定义类加载器 WebAppClassLoader 打破了双亲委派机制&#xff0c;它首先自己尝试去加载某个类&#xff0c;如果找不到再代理给父类加载器&#xff0c;其目的是优先加载 Web 应用自己定义的类。具体实现就是重写 ClassLoader 的两个方法…...

使用ffmpeg和python脚本下载网络视频m3u8(全网最全面)

网上给娃找了些好看的电影和一些有趣的短视频&#xff0c;如何保存下来呢&#xff1f;从网上找各种工具&#xff1f;都不方便。于是想到何不编程搞定&#xff0c;搞个脚本。对程序员来说这都不是事儿。且我有华为云服务器&#xff0c;完全可以把地址记下&#xff0c;后台自动下…...

【考研408常用数据结构】C/C++实现代码汇总

文章目录 前言数组多维数组的原理、作用稀疏数组 链表单向链表的增删改查的具体实现思路约瑟夫环问题&#xff08;可不学&#xff09;双向链表 树二叉搜索树中序线索二叉树哈夫曼树的编码与译码红黑树B树B树 堆顺序与链式结构队列实现优先队列排序算法&#xff08;重点&#xf…...

Flink学习笔记(二):Flink内存模型

文章目录 1、配置总内存2、JobManager 内存模型3、TaskManager 内存模型4、WebUI 展示内存5、Flink On YARN 模式下内存分配6、Flink On Yarn 集群消耗资源估算6.1、资源分配6.2、Flink 提交 Yarn 集群的相关命令6.3、Flink On Yarn 集群的资源计算公式 1、配置总内存 Flink J…...

信息系统项目管理师第四版学习笔记——项目绩效域

干系人绩效域 干系人绩效域涉及与干系人相关的活动和职能。在项目整个生命周期过程中&#xff0c;有效执行本绩效域可以实现的预期目标主要包含&#xff1a;①与干系人建立高效的工作关系&#xff1b;②干系人认同项目目标&#xff1b;③支持项目的干系人提高了满意度&#xf…...

PyTorch 深度学习之加载数据集Dataset and DataLoader(七)

1. Revision: Manual data feed 全部Batch&#xff1a;计算速度&#xff0c;性能有问题 1 个 &#xff1a;跨越鞍点 mini-Batch:均衡速度与性能 2. Terminology: Epoch, Batch-Size, Iteration DataLoader: batch_size2, sheffleTrue 3. How to define your Dataset 两种处…...

小谈设计模式(26)—中介者模式

小谈设计模式&#xff08;26&#xff09;—中介者模式 专栏介绍专栏地址专栏介绍 中介者模式分析角色分析抽象中介者&#xff08;Mediator&#xff09;具体中介者&#xff08;ConcreteMediator&#xff09;抽象同事类&#xff08;Colleague&#xff09;具体同事类&#xff08;C…...

7种设计模式

1. 工厂模式 优点&#xff1a;封装了对象的创建过程&#xff0c;降低了耦合性&#xff0c;提供了灵活性和可扩展性。 缺点&#xff1a;增加了代码的复杂性&#xff0c;需要创建工厂类。 适用场景&#xff1a;当需要根据不同条件创建不同对象时&#xff0c;或者需要隐藏对象创建…...

el-table合计行合并

效果如下 因为合计el-table的合并方法是不生效的,所以需要修改css下手 watch: {// 应急物资的合计合并planData: {immediate: true,handler() {setTimeout(() > {const tds document.querySelectorAll(".pro_table .el-table__footer-wrapper tr>td");tds[0]…...

新手如何快速上手HTTP爬虫IP?

对于刚接触HTTP爬虫IP的新手来说&#xff0c;可能会感到有些困惑。但是&#xff0c;实际上HTTP爬虫IP并不复杂&#xff0c;只要掌握了基本的操作步骤&#xff0c;就可以轻松使用。本文将为新手们提供一个快速上手HTTP爬虫IP的入门指南&#xff0c;帮助您迅速了解HTTP爬虫IP的基…...

(十五)VBA常用基础知识:正则表达式的使用

vba正则表达式的说明 项目说明Pattern在这里写正则表达式&#xff0c;例&#xff1a;[\d]{2,4}IgnoreCase大小写区分&#xff0c;默认false&#xff1a;区分&#xff1b;true&#xff1a;不区分Globaltrue&#xff1a;全体检索&#xff1b;false&#xff1a;最小匹配Test类似p…...