MySQL45讲 第二十三讲 是怎么保证数据不丢的?

news2024/11/16 5:35:36

文章目录

  • MySQL45讲 第二十三讲 是怎么保证数据不丢的?
    • 一、binlog 写入机制
      • (一)事务执行与 binlog cache
      • (二)事务提交与 binlog 文件写入
    • 二、redo log 写入机制
      • (一)事务执行与 redo log buffer
      • (二)redo log 的三种状态
      • (三)事务提交与 redo log 持久化
      • (四)组提交机制
    • 三、“双 1” 配置及其他设置
      • (一)“双 1” 配置
      • (二)其他设置及风险
    • 四、相关问题解答
      • (一)执行 update 语句后数据未改变
      • (二)binlog cache 与 redo log buffer 设计差异
      • (三)事务执行期间 crash 对主备一致性的影响
      • (四)binlog 写完盘后 crash 的情况
    • 五、总结与思考

MySQL45讲 第二十三讲 是怎么保证数据不丢的?

在 MySQL 的世界里,数据的可靠性是至关重要的。今天,我们将深入探讨 MySQL 是如何保证数据不丢的,这涉及到 binlog 和 redo log 的写入机制,以及一些关键参数的设置。


一、binlog 写入机制

(一)事务执行与 binlog cache

事务执行过程中,binlog 先被写到 binlog cache(缓存)。每个线程都有自己独立的 binlog cache,这是因为 binlog 不能被拆开,一个事务的 binlog 必须一次性完整写入。系统通过参数 binlog_cache_size 控制单个线程内 binlog cache 所占内存大小,若超出,需暂存到磁盘

(二)事务提交与 binlog 文件写入

事务提交时,执行器将 binlog cache 里的完整事务写入 binlog 文件,并清空 binlog cache。这里涉及到 write 和 fsync 两个操作,write 是将日志写入文件系统的 page cache,速度较快;fsync 才是将数据持久化到磁盘,通常认为 fsync 占磁盘 IOPS。write 和 fsync 的时机由参数 sync_binlog 控制。

虽然每个线程有自己的 binlog cache,但所有线程共用同一份 binlog 文件。

在这里插入图片描述

  1. sync_binlog = 0:每次提交事务只 write,不 fsync,由后台线程每秒一次将 page cache 中的数据持久化到磁盘。这种方式在主机异常重启时,可能丢失最近 1 秒内事务的 binlog 日志。
  2. sync_binlog = 1:每次提交事务都会执行 fsync,保证了数据的安全性,但性能相对较低。
  3. sync_binlog = N(N>1):每次提交事务 write,但累积 N 个事务后才 fsync。在出现 IO 瓶颈时,可提升性能,但主机异常重启会丢失最近 N 个事务的 binlog 日志。在实际业务场景中,常将 sync_binlog 设置为 100 - 1000 中的某个数值。

二、redo log 写入机制

(一)事务执行与 redo log buffer

事务执行过程中,生成的 redo log 先写到 redo log buffer。与 binlog 不同,redo log buffer 是全局共用的,因为 redo log 中间生成的日志可以写到 buffer 中,且其他事务提交时,redo log buffer 中的内容可 “搭便车” 一起写到磁盘。

(二)redo log 的三种状态

  1. 存在 redo log buffer 中:物理上在 MySQL 进程内存中。
  2. 写到磁盘(write)但未持久化(fsync):物理上在文件系统的 page cache 中。
  3. 持久化到磁盘:对应 hard disk。

在这里插入图片描述

(三)事务提交与 redo log 持久化

事务提交时,redo log 的持久化策略由参数 innodb_flush_log_at_trx_commit 控制。

  1. 设置为 0:事务提交时,redo log 只留在 redo log buffer 中,后台线程每秒一次将 redo log buffer 中的日志 write 到 page cache,并调用 fsync 持久化到磁盘。若事务执行期间 MySQL 异常重启,这部分日志丢失,但事务未提交,所以无损失。
  2. 设置为 1:事务提交时,redo log 直接持久化到磁盘。在 redo log 的 prepare 阶段就会进行持久化,这是因为崩溃恢复逻辑依赖于 prepare 的 redo logbinlog 来恢复数据。
  3. 设置为 2:事务提交时,redo log 写到 page cache。除后台线程每秒一次的轮询操作外,当 redo log buffer 占用空间即将达到 innodb_log_buffer_size 一半时,后台线程会主动 write 到 page cache(但不 fsync);并行事务提交时,也会顺带将未提交事务的 redo log buffer 持久化到磁盘。

(四)组提交机制

为提升性能,MySQL 引入了组提交机制。以三个并发事务(trx1、trx2、trx3)为例,在 prepare 阶段,它们都写完 redo log buffer 并持久化到磁盘,此时 LSN 分别为 50、120 和 160。trx1 作为组内第一个到达的事务(leader),当它写盘时,会将 LSN 为 160 及之前的 redo log 都持久化到磁盘,然后 trx2 和 trx3 可直接返回。一次组提交中,组员越多,节约磁盘 IOPS 的效果越好。为让 binlog 也能更好地组提交,MySQL 将 redo logfsync 的时间拖到 binlog write 到磁盘之后,这样 binlog 也可实现组提交,但通常 bin log 组提交效果不如 redo log,可通过设置 binlog_group_commit_sync_delaybinlog_group_commit_sync_no_delay_count 来提升 binlog 组提交效果。

在这里插入图片描述


三、“双 1” 配置及其他设置

(一)“双 1” 配置

通常所说的 MySQL “双 1” 配置,即sync_binloginnodb_flush_log_at_trx_commit 都设置为 1。这意味着一个事务完整提交前,需要等待两次刷盘,一次是 redo log(prepare 阶段),一次是 binlog,保证了数据的安全性,但对磁盘 IOPS 要求较高。

(二)其他设置及风险

  1. 提升 binlog 组提交效果:设置 binlog_group_commit_sync_delaybinlog_group_commit_sync_no_delay_count 参数,可减少 binlog 写盘次数,但可能增加语句响应时间,不过无数据丢失风险。
  2. sync_binlog 大于 1:将 sync_binlog 设置为大于 1 的值(如 100 - 1000),可提升性能,但主机掉电时会丢 binlog 日志。
  3. innodb_flush_log_at_trx_commit 设置为 2:可提升性能,主机掉电时可能丢数据,但相比设置为 0 风险更小,因为设置为 0 时,redo log 只保存在内存中,MySQL 异常重启也会丢数据。

四、相关问题解答

(一)执行 update 语句后数据未改变

执行 update 语句后,通过 hexdump 命令查看 ibd 文件内容未发现数据改变,这是因为 WAL 机制,update 语句执行完成后,InnoDB 可能只保证写完了 redo log 和内存,还未将数据写到磁盘。

(二)binlog cache 与 redo log buffer 设计差异

**binlog 是不能被打断的,一个事务的 binlog 必须连续写,所以每个线程自己维护 binlog cache,事务完成后再一起写入文件。**而 redo log 没有此要求,中间生成的日志可写到全局共用的 redo log buffer 中,且可借助其他事务提交时 “搭便车” 写到磁盘。

(三)事务执行期间 crash 对主备一致性的影响

事务执行期间,若还未到提交阶段发生 crash,redo log 虽可能丢失,但 binlog 也在 binlog cache 中未发给备库,从业务角度看事务未提交,所以主备数据是一致的。

(四)binlog 写完盘后 crash 的情况

binlog 写完盘后发生 crash,若未给客户端答复就重启,客户端重连后发现事务已提交成功,这并非 bug。因为数据库的 crash - safe 保证若客户端收到事务成功消息,事务一定持久化;若收到事务失败消息,事务一定失败;若收到 “执行异常” 消息,应用需重连后查询当前状态继续后续逻辑,此时数据库只需保证内部数据和日志、主库和备库之间一致即可。


五、总结与思考

通过对 binlog 和 redo log 写入机制的详细介绍,以及对相关参数的分析,我们了解到 MySQL 如何从多个方面保证数据不丢。“双 1” 配置提供了较高的数据安全性,但在性能和 IO 资源上有一定要求;其他设置虽可提升性能,但伴随着不同程度的数据丢失风险。

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

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

相关文章

pgaudit插件-pgslq

使用pgaudit插件 一.介绍 postgresql可以通过log_statementall 提供日志审计,但是无法详细的提供日志信息,使用ogaudit能够提供详细的会话和对象审计日志,是PG的一个扩展插件 注意:pgAudit可能会生成大量日志。请谨慎确定要在您…

系统掌握大语言模型提示词 - 从理论到实践

以下是我目前的一些主要个人标签: 6 年多头部大厂软件开发经验;1 年多 AI 业务应用经验,拥有丰富的业务提示词调优经验和模型微调经验。信仰 AGI,已经将 AI 通过自定义 Chatbot /搭建 Agent 融合到我的工作流中。头部大厂技术大学…

Vue 项目打包后环境变量丢失问题(清除缓存),区分.env和.env.*文件

Vue 项目打包后环境变量丢失问题(清除缓存),区分.env和.env.*文件 问题背景 今天在导报项目的时候遇到一个问题问题:在开发环境中一切正常,但在打包后的生产环境中,某些环境变量(如 VUE_APP_B…

群控系统服务端开发模式-应用开发-前端菜单功能开发

今天优先开发菜单及角色,明天将开发岗位配置、级别配置等功能。具体看下图 而前端的路由不需要手动添加,是依据数据库里面存储的路径。 一、添加视图 在根目录下src文件夹下views文件夹下permission文件夹下menu文件夹下,新建index.vue&…

数据结构Python版

2.3.3 双链表 双链表和链表一样,只不过每个节点有两个链接——一个指向后一个节点,一个指向前一个节点。此外,除了第一个节点,双链表还需要记录最后一个节点。 每个结点为DLinkNode类对象,包括存储元素的列表data、…

【HarmonyOS学习日志(8)】UIAbility,HAP,AbilityStage组件及其生命周期

基本概念 UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。 在项目创建时,系统默认生成的EntryAbility类继承了UIAbility类。 ExtensionAbility组件:是基于特定场景(例如服务卡片、输入法等)提供的应用组件…

【Linux】多线程(中)

目录 一、线程互斥 1.1 互斥概念 1.2 互斥量mutex 1.3 互斥量相关API (1)初始化互斥量 (2)销毁互斥量 (3)互斥量加锁和解锁 1.4 互斥量原理 1.5 重入和线程安全 二、死锁 2.1 概念 2.2 造成死锁…

【数字图像处理+MATLAB】基于 Sobel 算子计算图像梯度并进行边缘增强:使用 imgradientxy 函数

引言 在图像处理中,边缘通常是图像中像素强度变化最大的地方,这种变化可以通过计算图像的梯度来量化。梯度是一个向量,它的方向指向像素强度增加最快的方向,它的大小(或者说幅度)表示像素强度增加的速度。…

Nuxt.js 应用中的 schema:beforeWrite 事件钩子详解

title: Nuxt.js 应用中的 schema:beforeWrite 事件钩子详解 date: 2024/11/14 updated: 2024/11/14 author: cmdragon excerpt: schema:beforeWrite 钩子是 Vite 提供的一个功能强大的生命周期钩子,允许开发者在 JSON Schema 被写入之前执行自定义操作。利用这个钩子,您可以…

k8s服务内容滚动升级以及常用命令介绍

查看K8S集群所有的节点信息 kubectl get nodes 删除K8S集群中某个特定节点 kubectl delete nodes/10.0.0.123 获取K8S集群命名空间 kubectl get namespace 获取K8S所有命名空间的那些部署 kubectl get deployment --all-namespaces 创建命名空间 web界面上看到的效果,但是…

MinIo在Ubantu和Java中的整合

1.MinIo在Ubantu中的部署 首先准备好一台已经安装好Ubantu系统的服务器 MinIO是一个开源的对象存储服务器,兼容Amazon S3,性能卓越,适合存储非结构化数据,例如照片、视频、日志文件、备份和容器镜像等。 1:更新系统…

设计模式-参考的雷丰阳老师直播课

一般开发中使用的模式为模版模式策略模式组合,模版用来定义骨架,策略用来实现细节。 模版模式 策略模式 与模版模式特别像,模版模式会定义好步骤定义好框架,策略模式定义小细节 入口类 使用模版模式策略模式开发支付 以上使用…

【LeetCode】【算法】53. 最大子数组和

LeetCode 53. 最大子数组和 题目描述 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。 思路 思路:动态规划秒了 具体递推式如…

供应SW6301V单C口多协议升降压移动电源IC

1. 概述 SW6301V 是一款高集成度的单 C 口多协议升降压移动电源 SOC。集成双向升降压控制器,支持 2~6 节 电池串联,提供 100W 功 率 输 入 输 出 ; 支 持 C 口 快 充 输入输出 ; 支 持UFCS/PPS/PD/SVOOC/VOOC/SCP/FCP/QC/AFC/BC…

C++常用的新特性-->day06

时间间隔duration duration表示一段时间间隔&#xff0c;用来记录时间长度&#xff0c;可以表示几秒、几分钟、几个小时的时间间隔。duration的原型如下 // 定义于头文件 <chrono> template<class Rep,class Period std::ratio<1> > class duration;Rep&…

Cyberchef配合Wireshark提取并解析TCP/FTP流量数据包中的文件

前一篇文章中讲述了如何使用cyberchef提取HTTP/TLS数据包中的文件,详见《Cyberchef配合Wireshark提取并解析HTTP/TLS流量数据包中的文件》,链接这里,本文讲述下如何使用cyberchef提取FTP/TCP数据包中的文件。 FTP 是最为常见的文件传输协议,和HTTP协议不同的是FTP协议传输…

性能面向下一代PCIe Gen 5,G991B322HR、G99L12312HR 安费诺ExtremePort™ Swift连接器支持内部I/O应用

前言 为了在网络设备和服务器上提供更高速度和更小尺寸的解决方案&#xff0c;Amphenol开发了ExtremePort™ Swift连接器&#xff0c;适用于PCIe Gen5 NRZ 32GT/s、UPI 2.0 24GT/s、24Gb/s SAS信号。 G991B322HR G9912312HR G9912322HR G9914312HR G991B312HR G991C312HR G99…

IDEA调整警告级别【IntelliJ IDEA 2024.2.0.1】

文章目录 目前现状鼠标悬停&#xff0c;选择配置筛选 > 取消选择OK效果 目前现状 需要把提示改成只要显示error的5个 鼠标悬停&#xff0c;选择配置 筛选 > 取消选择 OK 效果

【二叉搜素树】——LeetCode二叉树问题集锦:6个实用题目和解题思路

文章目录 计算布尔二叉树的值求根节点到叶节点的数字之和二叉树剪枝验证二叉搜索树二叉搜索树中第K小的元素二叉树的所有路径 计算布尔二叉树的值 解题思路&#xff1a; 这是一个二叉树的布尔评估问题。树的每个节点包含一个值&#xff0c;其中叶子节点值为 0 或 1&#xff0…

windows下QT5.12.11使用MSVC编译器编译mysql驱动并使用详解

1、下载mysql开发库,后面驱动编译的时候需要引用到,下载地址:mysql开发库下载 2、使用everything搜索:msvc-version.conf,用记事本打开,添加:QMAKE_MSC_VER=1909。不然msvc下的mysql源码加载不上。