MySQL日志探索——redo log和bin log的刷盘时机详解

我们先简单了解一下大致的刷盘时机,然后配合两阶段提交和组提交来看

redo log的刷盘时机

  1. MySQL 正常关闭时;
  2. 当 redo log buffer 中记录的写入量大于 redo log buffer内存空间的一半时,会触发落盘;
    PS:为什么这里要到一半就要刷了,因为redo log buffer是一个环状的内存结构,会被反复利用
  3. InnoDB 的后台线程每隔 1 秒,将 redo log buffer 持久化到磁盘。
  4. 由系统参数innodb_flush_log_at_trx_commit 参数控制。

其中,innodb_flush_log_at_trx_commit 参数控制,可取的值有:0、1、2,默认值为 1,这三个值分别代表的策略如下:
1、当设置该参数为 0 时,表示每次事务提交时将 redo log 留在 redo log buffer 中 ,该模式下在事务提交时不会主动触发写入磁盘的操作。
2、当设置该参数为 1 时,表示每次事务提交时,都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘,这样可以保证 MySQL 异常重启之后数据不会丢失。
3、当设置该参数为 2时,表示每次事务提交时,都只是缓存在 redo log buffer 里的 redo log 写到 redo log 文件,这并不意味着写入到了磁盘,而是写到了操作系统的Page Cache。

参数为1的时候会主动持久化到磁盘,但是0和2不会,那么这两个什么时候持久化到磁盘呢?

InnoDB 的后台线程每隔 1 秒:
(1)针对参数 0 :会把缓存在 redo log buffer 中的 redo log ,通过调用 write() 写到操作系统的 Page Cache,然后调用 fsync() 持久化到磁盘。所以参数为 0 的策略,MySQL 进程的崩溃会导致上一秒钟所有事务数据的丢失;
(2)针对参数 2 :调用 fsync,将缓存在操作系统中 Page Cache 里的 redo log 持久化到磁盘。所以参数为 2 的策略,较取值为 0 情况下更安全,因为 MySQL 进程的崩溃并不会丢失数据,只有在操作系统崩溃或者系统断电的情况下,上一秒钟所有事务数据才可能丢失。

我们可以通过系统变量来查看这个参数

mysql> show variables like '%innodb_flush_log_at_trx_commit%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

好了,redo log介绍完了,接着我们来介绍bin log的刷盘时机。

bin log的刷盘时机

每个线程有自己 binlog cache,最终会都写到同一个 binlog 文件。

binlog的刷盘过程:
(1) write,指的就是指把日志写入到 binlog 文件,但是并没有把数据持久化到磁盘,因为数据还缓存在文件系统的 page cache 里,write 的写入速度还是比较快的,因为不涉及磁盘 I/O。
(2)fsync,才是将数据持久化到磁盘的操作,这里就会涉及磁盘 I/O,所以频繁的 fsync 会导致磁盘的 I/O 升高。

那么什么时候刷盘呢?
通过sync_binlog 参数来控制数据库的 binlog 刷到磁盘上的频率:

1、sync_binlog = 0 的时候,表示每次提交事务都只 write,不 fsync,后续交由操作系统决定何时将数据持久化到磁盘;
2、sync_binlog = 1 的时候,表示每次提交事务都会 write,然后马上执行 fsync;
3、sync_binlog= N (N>1) 的时候,表示每次提交事务都 write,但累积 N 个事务后才 fsync。

我们通过命令行来查看参数:

mysql> show variables like '%sync_binlog%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 1     |
+---------------+-------+
1 row in set (0.00 sec)

两次提交、组提交、双参数配合实现了两个日志的同步

有了前面两个刷盘时机,为什么还要有两次提交,因为我们需要保证redo log和bin log的一致性
两阶段提交的过程是如何的?
具体的取决于我们的参数,参数一共有四个分别如下所示:

mysql> show variables like '%sync_binlog%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 1     |
+---------------+-------+
1 row in set (0.00 sec)mysql> show variables like '%innodb_flush_log_at_trx_commit%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)mysql> show variables like '%binlog_group%';
+-----------------------------------------+---------+
| Variable_name                           | Value   |
+-----------------------------------------+---------+
| binlog_group_commit_sync_delay          | 1000000 |
| binlog_group_commit_sync_no_delay_count | 10      |
+-----------------------------------------+---------+
2 rows in set (0.00 sec)

其中,我们看到了两个新参数,他们是组提交参数:

1、 binlog_group_commit_sync_delay= N,表示在等待 N 微妙后,直接调用 fsync,将处于文件系统中 page cache 中的 binlog 刷盘,也就是将binlog 文件持久化到磁盘。表中值为1000000 (即1e6),就是1s。
2、 binlog_group_commit_sync_no_delay_count = N,表示如果队列中的事务数达到 N个,就忽视binlog_group_commit_sync_delay 的设置,直接调用 fsync,将处于文件系统中 page cache中的 binlog 刷盘。

不同的参数效果都是不一样的。

1、我们先来看最经典的双1配置
此刻事务提交时需要花费1.00 sec,因为binlog_group_commit_sync_delay设置的是1s,binlog_group_commit_sync_no_delay_count和binlog_group_commit_sync_delay满足其中一条即可

2、在双1的基础上,如果我们把innodb_flush_log_at_trx_commit改了呢?
每次redo log都没有刷盘,我们默认就成功了。

3、在双1的基础上,如果我们把sync_binlog改了呢?
此时事务提交只需要0.00sec,可以判定提交的瞬间未刷盘,但是提交成功了。因为sync_binlog=N,在后续的1~N-1的事务,commit都是很快,第N个事务commit所消耗的时间是1s左右。也就是在第N次时候,进行了刷盘。
这时候有人疑惑了,那么我的组提交参数有啥用?
我们来看结论:
开启两个并行的窗口,这两个窗口同时commit提交,并设置binlog_group_commit_sync_no_delay_count =2,我们发现刷盘了。 也就是说组提交在事务并行的时候才有效果。为什么要在并行事务的时候才有效果?

原来,早期的 MySQL 版本中,通过使用 prepare_commit_mutex 锁来保证事务提交的顺序,在一个事务获取到锁时才能进入
prepare 阶段,一直到 commit 阶段结束才能释放锁,下个事务才可以继续进行 prepare 操作。
通过加锁虽然完美地解决了顺序一致性的问题,但在并发量较大的时候,就会导致对锁的争用,性能不佳。

所以sync_binlog和组提交之间是相互配合而不是冲突矛盾的关系,在事务并发时组提交生效,而在没有并发时候,syc_binlog就发挥了巨大作用。

好了,关于日志刷盘的内容就到这了。

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

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

相关文章

Google Chrome 常用设置

Google Chrome 常用设置 References 转至网页顶部 快捷键:Home 转至内容设置 chrome://settings/content 清除浏览数据 历史记录 -> 清除浏览数据 关于 Chrome 设置 -> 关于 Chrome chrome://settings/help References [1] Yongqiang Cheng, https:/…

关于ansible的模块 ③

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 接《关于Ansible的模块①》和《关于Ansible的模块②》,继续学习ansible的user模块。 user模块可以增、删、改linux远…

回溯算法|491.递增子序列

力扣题目链接 class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex) {if (path.size() > 1) {result.push_back(path);// 注意这里不要加return&#xff0c;要取树上…

MySQL 索引优化(二)

书接上文&#xff0c;继续使用上次创建的 student 表&#xff0c;表里已经被我们装填了大量数据&#xff0c;接下来做分页查询的索引优化。 分页查询优化 普通的分页查询语句&#xff1a; SELECT * FROM student LIMIT 10000,10;这条语句是从 student 表中取出 10001 行开始…

面向对象进阶5:类和泛型

内部类 在一个类的内部定义的类,内部类可以访问外部类的成员变量和成员方法,包括私有成员,内部类可以分为成员内部类,局部内部类,静态内部类和匿名内部类 public class InnerClass {class InnerC{} }1,成员内部类 定义在类中方法外的类,可以访问外部类的所有成员变量和方法,…

人脸识别seetaface6 windows + cmake + vs编译,踩坑指南

遇到问题冷静分析&#xff0c;没有解决不了的问题&#xff0c;只是需要时间。与君共勉 环境准备 要在windows 上编译c 源码&#xff0c;需要准备如下软件。省去了详细的安装过程。 visual studio 2022 (社区免费版链接)mingw64 下载路径 (安装后&#xff0c;记得添加系统路径…

elementui 实现一个固定位置的Pagination(分页)组件

系列文章目录 一、elementui 导航菜单栏和Breadcrumb 面包屑关联 二、elementui 左侧导航菜单栏与main区域联动 三、elementui 中设置图片的高度并支持PC和手机自适应 四、 elementui 实现一个固定位置的Pagination&#xff08;分页&#xff09;组件 文章目录 系列文章目录…

今客CRM客户管理系统 v17.3

简介&#xff1a; 今客CRM客户管理系统主要是为了帮助企业解决在日常工作中遇到的客户管理等难题而开发&#xff0c;通过今客CRM客户管理系统可以对企业事务中的不同功能进行操作&#xff0c;用户通过自定义字段类型可以达到适合不同企业的需求。在今客客户关系管理系统中管理…

【子集回溯】【树枝+树层去重】Leetcode 491. 非递减子序列

【组合回溯】【树枝树层去重】Leetcode 491. 非递减子序列 解法1 ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f388;------------------- 解法1 【树层去重】&#xff1a;如果在同层元素重复(这里无法排序&#xff0c;所以无法使用之前的flag&a…

Making Anti-Palindromes

题目链接 Codeforces Round 867 (Div. 3) E. Making Anti-Palindromes 挺好的一道鸽巢原理题。 思路&#xff1a; 贪心地来想&#xff0c;我们没必要动本来就不同的一对&#xff0c;而对相同的对&#xff0c;我们可以让它们互相之间进行交换&#xff0c;这样一次交换就可以…

HarmonyOS 应用开发之启动远程PageAbility(仅对系统应用开放)

启动远程PageAbility同样通过featureAbility中的startAbility接口实现。 除引入’ohos.ability.featureAbility’外&#xff0c;还需引入’ohos.distributedHardware.deviceManager’&#xff0c;通过DeviceManager&#xff08;该组件提供帐号无关的分布式设备的认证组网能力&…

鸿蒙南向开发实战:【智能窗帘】

样例简介 智能窗帘设备不仅接收数字管家应用下发的指令来控制窗帘开启的时间&#xff0c;而且还可以加入到数字管家的日程管理中。通过日程可以设定窗帘开关的时间段&#xff0c;使其在特定的时间段内&#xff0c;窗帘自动打开或者关闭&#xff1b;通过日程管家还可以实现窗帘…

蓝桥杯备考

目录 P8823 [传智杯 #3 初赛] 期末考试成绩 题目描述 输入格式 输出格式 输入输出样例 说明/提示 代码 P8828 [传智杯 #3 练习赛] 直角三角形 题目描述 输入格式 输出格式 输入输出样例 代码 P8833 [传智杯 #3 决赛] 课程 题目背景 题目描述 输入格式 输出格式…

redis---位图Bitmap和位域 Bitfield

位图是字符串类型的拓展&#xff0c;可以使用一个string类型来模拟一个Bit数组。数组的下标就是偏移量&#xff0c;值只有0和1&#xff0c;也支持一些位运算&#xff0c;比如与或非&#xff0c;异或等等&#xff0c;它们的应用场景非常广泛比如可以用来记录用户的签到情况&…

dict类型如何保存为json数据,给一个python示例代码

dict类型如何保存为json数据&#xff0c;给一个python示例代码 import json# 假设我们有一个字典对象 data_dict {"name": "Alice","age": 30,"city": "Wonderland" }# 将字典转换为JSON格式的字符串 json_string json.d…

代码随想录一刷总结(待更新)

文章目录 代码随想录一刷总结数组篇二分查找双指针用法 链表篇哈希表篇字符串篇栈与队列篇二叉树篇回溯篇贪心篇动态规划篇 代码随想录一刷总结 数组篇 二分查找 最重要的是循环不变量原理 区间定义 left right 时有没有意义&#xff0c;取决于开区间还是闭区间 使用场景…

Qt中继承QCheckBox的类结合QTableWidget实现多选并且每个多选的id都不一样

1.相关描述 继承QCheckBox的类MyCheckBox&#xff0c;利用QTableWidget的setCellWidget方式添加MyCheckBox类的对象 2.相关页面 3.相关代码 mycheckbox.h #ifndef MYCHECKBOX_H #define MYCHECKBOX_H#include <QCheckBox> #include <QObject>class MyCheckBox : pu…

力扣刷题Days31-2.两数相关(js)

1&#xff0c;题目 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;…

Vue3:Pinia简介及环境搭建

一、简介 Pinia是Vue3中的状态管理工具&#xff0c;类似与Vue2中的Vuex框架的作用 二、环境搭建 1、安装 npm install pinia2、配置 main.ts import {createApp} from vue import App from ./App.vue // 第一步&#xff1a;引入pinia import {createPinia} from piniacons…

Nginx - directory index of “/usr/share/nginx/html/“ is forbidden

问题描述 安装完 Nginx 之后访问本机 IP&#xff0c;结果直接报错&#xff0c;然后去查看 Nginx 错误日志&#xff0c;看到如下错误信息&#xff0c;意思是 html 下面没有 directory index of "/usr/share/nginx/html/" is forbidden 解决方案 Q1&#xff1a;如果在…