23 | MySQL是怎么保证数据不丢的?

news2024/12/26 15:05:11

以下内容出自《MySQL 实战 45 讲》

23 | MySQL是怎么保证数据不丢的?

binlog 的写入机制

1、事务执行过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到 binlog 文件中。

2、一个事务的 binlog 是不能被拆开的,因此不论这个事务多大,也要确保一次性写入。

3、系统给每个线程分配了一片 binlog cache 内存,参数 binlog_cache_size 用于控制单个线程内 binlog cache 所占内存的大小。如果超过了这大小,就要暂存到磁盘。

4、事务提交的时候,执行器把 binlog cache 里的完整事务写入到 binlog 中,并清空 binlog cache。

5、每个线程有自己 binlog cache,但是共用同一份 binlog 文件。

6、下图中的 write, 将日志写入到文件系统的 page cache,在内存中,所以速度很快;fsync 将数据持久化到磁盘,占用磁盘 IOPS。

在这里插入图片描述

参数 sync_binlog

  • sync_binlog = 0, 表示每次提交事务都只 write ,不 fsync
  • sync_binlog = 1, 表示每次提交事务都会执行 fsync
  • sync_binlog = N(N > 1), 表示每次提交事务都只 write,但累计 N 个事务后才 fsync。

IO 瓶颈的场景中,将 sync_binlog 设置成一个较大的值,可以提升性能。但是对应风险就是,如果主机异常重启,会丢失最近 N 个事务的 binlog 日志。

redo log 的写入机制

事务在执行过程中,生成的 redo log 是要先写到 redo log buffer 的。

在这里插入图片描述

innodb_flush_log_at_trx_commit 参数控制 redo log 的写入策略

  • innodb_flush_log_at_trx_commit = 0, 表示每次提交事务都只是把 redo log 留在 redo log buffer 中,redo log buffer 是所有线程共用的。(上图红色部分)
  • innodb_flush_log_at_trx_commit = 1, 表示每次提交事务时都将 redo log 直接持久化到磁盘。(上图绿色部分)
  • innodb_flush_log_at_trx_commit = 2, 表示每次提交事务时都只是把 redo log 写到 page cache。(上图黄色部分)

InnoDB 的后台线程每隔 1 秒。就会把 redo log buffer 中的日志调用 write 写到文件系统的 page cache ,然后调用 fsync 持久化到磁盘 。

PS: 事务执行中间过程的 redo log 也是直接写在 redo log buffer 中的,这些 redo log 也会被后台线程一起持久化到磁盘。也就是说,一个没有提交的事务的 redo log,也是可能已经持久化到磁盘的。

一个没有提交的事务的 redo log 写入到磁盘的三种场景

  • 后台线程每秒一次的轮询操作
  • redo log buffer 占用空间达到 innodb_log_buffer_size 一半的时候,后台线程主动写盘。(注意,由于事务没有提交,这个写盘仅会写入到 page cache)
  • 并行的事务提交的时候,顺带将这个事务的 redo log buffer 持久化到磁盘。innodb_flush_log_at_trx_commit = 1 时,把 redo log buffer 里的日志全部持久化到磁盘。

组提交机制(group commit)

目的:节约磁盘 IOPS。提高 MySQL TPS

日志逻辑序列号(log sequence number,LSN):LSN 是单调递增的,用来对应 redo log 的一个个写入点。每次写入长度为 length 的 redo log, LSN 的值就会加上 length。

LSN 也会写到 InnoDB 的数据页中,来确保数据页不会被多次执行重复的 redo log。

在这里插入图片描述

上图是三个并发事务 (trx1, trx2, trx3) 在 prepare 阶段,都写完 redo log buffer,持久化到磁盘的过程,对应的 LSN 分别是 50、120 和 160。

  • trx1 是第一个到达的,会被选为这组的 leader;
  • 等 trx1 要开始写盘的时候,这个组里面已经有了三个事务,这时候 LSN 也变成了 160;
  • trx1 去写盘的时候,带的就是 LSN=160,因此等 trx1 返回时,所有 LSN 小于等于 160 的 redo log,都已经被持久化到磁盘;
  • 这时候 trx2 和 trx3 就可以直接返回了。

在并发更新场景下,第一个事务写完 redo log buffer 以后,接下来这个 fsync 越晚调用,组员可能越多,节约 IOPS 的效果就越好。为了让一次 fsync 带的组员更多,MySQL 有一个很有趣的优化:拖时间。

两阶段提交的细化过程如下图:

在这里插入图片描述

第 4 步把 binlog fsync 到磁盘时,如果有多个事务的 binlog 已经写完了,也是一起持久化的,这样也可以减少 IOPS 的消耗。但是一般第 3 步执行的很快,导致 binlog write 和 fsync 间隔很短,binlog 组提交的效果不如 redo log 的组提交效果好。

提升 binlog 组提交的效果,可以通过设置 binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count,这两个参数是或的关系。满足一个条件就会 fsync。

  • binlog_group_commit_sync_delay :表示延迟多少微秒后才调用 fsync;默认为 0
  • binlog_group_commit_sync_no_delay_count:表示累积多少次以后才调用 fsync。默认为 0

这两个参数是基于额外的故意等待来实现的,会阻止客户端的响应。没有丢失数据的风险。

WAL 机制主要得益于两个方面:

1、redo log 和 binlog 都是顺序写,磁盘的顺序写比随机写速度要快;

2、组提交机制,可以大幅度降低磁盘的 IOPS 消耗。

MySQL 出现 IO 性能瓶颈

1、设置 binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count 参数,减少 binlog 的写盘次数。

2、将 sync_binlog 设置为大于 1 的值(比较常见是 100~1000)。这样做的风险是,主机掉电时会丢 binlog 日志。

3、将 innodb_flush_log_at_trx_commit 设置为 2。这样做的风险是,主机掉电的时候会丢数据。

数据库的 crash-safe

实际上数据库的 crash-safe 保证的是:

1、如果客户端收到事务成功的消息,事务就一定持久化了;

2、如果客户端收到事务失败(比如主键冲突、回滚等)的消息,事务就一定失败了;

3、如果客户端收到“执行异常”的消息,应用需要重连后通过查询当前状态来继续后续的逻辑。此时数据库只需要保证内部(数据和日志之间,主库和备库之间)一致就可以了。

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

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

相关文章

rust学习-所有权

运行程序必须管理使用内存的方式 (1)一些语言中具有垃圾回收机制,程序运行时不断寻找不再使用的内存 (2)一些语言中,开发者必须亲自分配和释放内存 (3)Rust 通过所有权系统管理内存…

Windows操作系统安全加固

Windows操作系统安全加固 一、安全加固基本思路1.1、安全基线1.2、系统信息审查 二、Windows安全配置加固2.1、漏洞修复——补丁安装2.2、漏洞修复——端口封禁2.2.1、windows高危端口加固实践——封禁135端口对外开放 2.3、安全配置加固——账号口令 一、安全加固基本思路 1.…

10.20UEC++/代理,单播,多播

构建一个无参无返回值类型的函数(也可以有参有返回值类型) 相对应的构建一个无参无返回值类型的代理

【计算机组成与体系结构课程设计】上机考试

1 (1) 针对图中的MIPS处理器数据通路(不考虑I/O),用红色或蓝色描出执行sw指令时的数据通路。(将该图下载到电脑,并用画图完成描线) (2) 写出执行sw指令时,各个元件控制端信号应该置什么值? 2 基于Minisys处理…

Qt保存代码

补全保存代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//字体按钮对应的槽函数 void Widget::on_fontBtn_clicked() {…

使用常见的三个命令分析线程的信息

目录 jps jstack.exe jvisualvm.exe jmc.exe 这三个都在jdk\bin文件夹中!!! 查看线程等待状态与信息可以采用3种常见命令。 本文中针对以下代码进行演示 package ChapterOne.test;public class Run3 {public static void main(String[…

Coggle 30 Days of ML(23年7月)任务四:线性模型训练与预测

Coggle 30 Days of ML(23年7月)任务四:线性模型训练与预测 任务四:使用TFIDF特征和线性模型完成训练和预测 说明:在这个任务中,你需要使用TFIDF特征和线性模型(如逻辑回归)完成训练…

图像处理-比特平面分层和重构

一、比特平面分层 像素是由比特组成的数字。例如在256级灰度图像中,每个像素的灰度是由8比特(一个字节)组成。如下图所示,一幅8比特图像由8个1比特平面组成,其中平面1包含图像中所有像素的最低阶比特,而平…

人工智能(pytorch)搭建模型17-pytorch搭建ReitnNet模型,加载数据进行模型训练与预测

大家好,我是微学AI,今天给大家介绍一下人工智能(pytorch)搭建模型17-pytorch搭建ReitnNet模型,加载数据进行模型训练与预测,RetinaNet 是一种用于目标检测任务的深度学习模型,旨在解决目标检测中存在的困难样本和不平衡…

前端Vue仿京东淘宝我的优惠券列表组件 用于电商我的优惠券列表页面

随着技术的发展,开发的复杂度也越来越高,传统开发方式将一个系统做成了整块应用,经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改,造成牵一发而动全身。 通过组件化开发,可以有效实现…

C++之子类指向父类,父类指向子类总结(一百五十五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

nginx配置例子-动静分离实例

动静分离实例 1.准备工作 步骤一:在 根目录/ 下 创建 目录data/www 和 data/image 步骤二:在目录www 下 ,创建a.html文件 步骤三:在目录image下,将图片拖到Xshell客户端,实现图片导入Linux,导…

ITIL 4—发布管理实践

2 基本信息 2.1 目的和描述 关键信息 发布管理实践的目的是使新的和变更的服务及功能均可用。 发布管理实践是为了确保组织及其服务使用者在符合组织政策和协议的前提下,服务可以正常使用而产生的最佳实践。 传统场景下,服务组件(包括基…

QT -20230709

练习&#xff1a; 登录界面增加注册功能(在本地增加用户文件进行比对用户) LoginWindow.h #ifndef LOGINWINDOW_H #define LOGINWINDOW_H#include <QMainWindow> #include <QIcon> #include <QLabel> #include <QLineEdit> #include <QPushButto…

TCP Socket性能优化秘籍:掌握read、recv、readv、write、send、sendv的最佳实践

TCP Socket性能优化秘籍&#xff1a;掌握read、recv、readv、write、send、sendv的最佳实践 博主简介一、引言1.1、TCP Socket在网络通信中的重要性1.2、为什么需要优化TCP Socket的性能&#xff1f; 二、TCP Socket读操作的性能优化2.1、read、recv、readv的功能和用法2.2、提…

有哪些做的问卷调查的工具?

想要洞察市场变化、了解某个特定群体的喜好等情况&#xff0c;使用问卷调查是常见的方法。而互联网的发展&#xff0c;越来越多的人转战网络问卷&#xff0c;而功能各异的问卷工具却让人挑花眼。今天&#xff0c;我们精准针对大家的需求和常见的一些问题&#xff0c;为大家聊一…

ASPICE汽车软件能力如何评估

第一节我们介绍了&#xff1a;什么是ASPICE 上一节我们介绍了&#xff1a;什么是aspice认证 这一节我们看一看&#xff1a;ASPICE汽车软件能力是如何评估 为了使汽车电控系统的研发具有统一的流程和规范的标准&#xff0c;并且使整个开发进度具有可控性和可预测阻借用具有国际…

利用Anaconda完成Python环境安装及配置

1 Anaconda 1.1 配置过程 Anaconda是一个开源的Python和R编程语言的软件包管理器和环境管理器&#xff0c;用于数据科学和机器学习的开发。 进入官网https://www.anaconda.com/下载安装包next->argee进入下列界面&#xff0c;选择Just Me 选择安装路径&#xff0c;点击Ne…

Swagger-Bootstrap-UI

Swagger-Bootstrap-UI 是一个为 Swagger 提供美观、易用的界面展示和增强功能的开源项目。它通过自定义样式和交互&#xff0c;提供了更好的文档展示和交互体验&#xff0c;包括美化的界面、接口测试工具、在线调试、文档导出等功能。 更高阶的有Knife4j,Knife4j是一个集Swagg…

本地部署 ChatPPT

本地部署 ChatPPT 1. 什么是 ChatPPT2. Github 地址3. 安装 Miniconda34. 创建虚拟环境5. 安装 ChatPPT6. 运行 ChatPPT 1. 什么是 ChatPPT ChatPPT由chatgpt提供支持&#xff0c;它可以帮助您生成PPT/幻灯片。支持中英文输出。 2. Github 地址 https://github.com/huimi24/…