【MySQL】深入解析日志系统:undo log、redo log、bin log

文章目录

      • 前言
      • 1、undo log
        • 1.1、undo log 是什么
        • 1.2、事务回滚
      • 2、redo log
        • 2.1、redo log 是什么
        • 2.2、redo log 刷盘
        • 2.3、redo log 硬盘文件
      • 3、bin log
        • 3.1、bin log 是什么
        • 3.2、bin log 和 redo log 区别
        • 3.3、bin log 刷盘
        • 3.4、两阶段提交

前言

MySQL数据库提供了功能强大的日志系统,其中比较重要的是:undolog、redolog、binlog,今天来深入学习下这三个日志实现细节。

1、undo log

1.1、undo log 是什么

undolog一般叫回滚日志,事务回滚rollback功能就是通过undolog实现的,通过undolog保证了为事务原子性undolog主要功能如下:

  • 事务回滚
  • MVCC
1.2、事务回滚

当开启一段事务还未提交时,事务中的操作可能会出现错误异常,这时候就可以通过undo log将事务中的操作进行回滚(rollback),意思是回到事务开启前那个状态。例如:开启事务后我对表中某条记录进行修改(将该记录字段值由a ——> b ——> c),如果从整个修改过程中出现异常,事务就会回滚,字段的值就回到最初的起点(值为a)。

事务如何通过undo log进行回滚操作呢?这个很好理解,我们只需要在undo log日志中记录事务中的反向操作即可,发生回滚时直接通过undolog中记录的反向操作进行恢复,例如:

事务进行insert操作,undo log记录delete操作
事务进行delete操作,undo log记录insert操作
事务进行update操作(a改为b),undolog记录update操作(b改为a)

接下来了解一下事务是如何通过undo log完成回滚的(undo log版本链),这就不得不通过一张图直观的表达undo log记录了:

在这里插入图片描述
上图中,trx_id代表事务id,记录了这一系列事务操作是基于哪个事务;roll_pointer代表回滚指针,就是当要发生rollback回滚操作时,就通过roll_pointer进行回滚,这个链表称为版本链

buffer pool 中有 undo 页,不仅对数据页修改操作会记录到redo log buffer,对 undo 页修改操作也会记录到 redo log buffer,这样就通过redo log保证了事务持久性。当事务Commit之后,undo 页本身就没有利用价值了,此时通过后台线程中的Master ThreadPurge Thread进行 undo 页 的回收工作。
在这里插入图片描述

2、redo log

2.1、redo log 是什么

redo log又称重做日志,保证了事务的持久性,当我们对缓冲池中的数据页进行了修改(变成了脏页),缓冲池本身就是操作系统内存分配的空间,所以数据页本质也是存在内存中的,内存有个特点就是断电即失。所以如果脏页还没有刷入磁盘,数据库服务发生宕机,那么脏页数据就会因为宕机而丢失,这时候redo log就派上了用场。
在这里插入图片描述

redo log通过WAL(Write-Ahead Logging)来进行故障恢复(crash-safe),所谓WAL就是先写日志,后写磁盘。当我们对缓存页进行了修改(变成脏页),我们就将本次操作先写入到redo log buffer中,当事务Commit时就会将redo log buffer中记录通过后台线程刷到磁盘中(事务提交是redo log默认刷盘时机),这时脏页还没有刷盘,但依旧可以认为本次的操作完成了,因为就算发生了故障脏页数据丢失也可以通过redo log恢复,需要注意redo log记录的是物理操作,例如:对AAA数据页BBB偏移量位置做了CCC更新,这跟undo log区别还是挺大的。

事务提交崩溃,通过 undo log 回滚事务
事务提交崩溃,通过 redo log 恢复事务

2.2、redo log 刷盘

上面已经介绍过了,redo log记录先写入到redo log buffer中,然后通过后台线程进行刷盘,也就是说最后还是从 redo log buffer 同步到硬盘中,那么redo log buffer何时进行刷盘操作呢?主要是以下几种情况:

  • Master Thread每秒刷盘一次
  • redo log buffer 剩余空间 < 1/2
  • 通过innodb_flush_log_at_trx_commit参数控制
    • 0:有事务提交的情况下,每秒刷盘一次
    • 1:每次提交事务,刷盘一次(默认,性能差)
    • 2:每次提交事务,把日志记录放到OS内核缓冲区,刷盘时机交给OS(性能好)

默认情况下,redo log在事务提交时就会进行一次刷盘。这有个疑问点,为啥事务提交时不直接将脏页刷盘呢,干嘛还要将 redo log buffer 中记录进行刷盘,然后脏页再刷盘呢,这不多了一步流程吗?

之所以这样设计是因为 redo log 刷盘操作采用磁盘顺序写方式进行的
这种方式性能相比于缓存页随机写方式性能好很多

2.3、redo log 硬盘文件

上面提到了redo log的刷盘操作采用顺序写方式进行,接下来咱们看下 redo log 文件在硬盘中是怎样的方式存在的。

redo log文件好像一个甜甜圈🍩,它是以ib_logfile文件组形式存在(也就是多个ib_logfile构成一个重做日志组),每个重做日志组中最少2个ib_logfile,每个ib_logfile占用内存1GB,当ib_logfile-1写满之后就开始写入ib_logfile2,以此类推:图片来自于《MySQL实战45讲》

在这里插入图片描述

上图中的重做日志组包含了4个重做日志文件ib_logfile,按照圆环顺时针顺序写入文件,这种写入磁盘的方式也叫循环写

  • write pos:当前redo log文件写到了哪个位置
  • check point:目前redo log文件哪些记录可以被覆盖

两个指针中间绿色部分表示还剩余多少可写入空间,也就是redo log 文件的可用空间了,当数据页进行刷盘操作(CheckPoint)时,check point指针也会顺时针进行覆盖(黄色变成绿色);当write pos追上了check point就说明 redo log 文件存满了,那就要强制CheckPoint了,将缓冲池中的脏页刷盘,然后再移动check point指针,这样就可以继续向重做日志组中写入数据了。说到这里大家就该明白,当数据页刷盘后,check point也会顺时针移动,将无用的redo log记录覆盖掉。所以redo log大小需要好好斟酌,如果太大那么故障恢复crash-safe时间会很久;如果太小就会频繁发生刷盘导致性能抖动!

3、bin log

3.1、bin log 是什么

bin log常称作二进制日志,该日志主要有两个功能:

  • 备份恢复
  • 主从复制

每次事务进行提交时,都会将增、删、改操作以追加的方式记录到bin log文件中。这样也就理解了为什么该日志具备备份恢复和主从复制的功能,关于备份恢复比较好理解,根据bin log日志中记录的二进制操作记录恢复即可;主从复制常用于MySQL主从集群搭建,MySQL从节点通过监听主节点bin log日志进行同步即可。

3.2、bin log 和 redo log 区别

bin logredo log二者之间还是有很大的区别:

  1. bin log 属于MySQL体系架构的Server层,而 redo log是InnoDB存储引擎特有的。
  2. bin log 写入方式是追加写,而 redo log 写入方式是循环写
  3. bin log 中记录的是二进制日志(3种类型),而 redo log 中记录的是物理日志信息。
  4. bin log 用于备份恢复、主从复制,而 redo log 用于故障恢复。

关于bin log的二进制日志格式,有以下三种类型:

  1. STATEMENT:增删改SQL语句,存储空间要求小
  2. ROW:记录表行的更改情况,存储空间要求大
  3. MIXED:混合场景,默认情况下STATEMENT,少数情况下ROW

redo log 不具备数据备份功能的原因是由于 redo log 文件组采用的是循环写方式,所以当脏页刷盘时redo log文件组内容会进行覆盖;之所以bin log不具备crash-safe原因是我们很难判断到底从那个位置进行恢复,而redo logwrite poscheck point指针指明了哪些数据需要恢复。

3.3、bin log 刷盘

bin log属于MySQL体系架构的Server层,事务操作进行过程中,会把日志信息先记录到bin log cache中,等到事务提交后会将bin log cache中记录刷盘到bin log 文件中。

这里需要注意,无论一个事务中包含了多少个增删改操作,都要一次性写入,不可拆分。当一个线程执行事务操作时,MySQL就会为该线程分配bin log cache,而且一个线程某一时刻最多只能执行一个事务。

bin log 刷刷盘时机通过参数sync_binlog控制:

0:每次提交事务写到内核缓冲区,不刷盘(由OS决定何时刷盘)
1:每次提交事务写到内核缓冲区,马上刷盘
N:每次提交事务写到内核缓冲区,累积 N 个事务后才刷盘(N > 1)

3.4、两阶段提交

当事务进行Commit操作时,redo logbin log都会被刷盘持久化保存,但是可能会出现以下两种情况:

bin log刷盘后,redo log还未来得及刷盘,数据库宕机,数据不一致。
redo log刷盘后,bin log还未来得及刷盘,数据库宕机,数据不一致。

说到这里大概知道两阶段提交其实就是为了防止这两个日志不一致,它将事务Commit操作分为两个阶段:Prepare、Commit

  • Prepare:XID(内部 XA 事务的 ID) 写入到 redo log,同时将 redo log 对应的事务状态设置为 prepare,然后将 redo log 持久化到磁盘(默认redo log刷盘策略);
  • Commit:XID 写入到 bin log,马上将 bin log 刷盘(sync_binlog = 1),接着调用引擎的提交事务接口,将 redo log 状态设置为 commit,只要 bin log 写磁盘成功,就算 redo log 的状态还是 prepare 也没有关系,一样会被认为事务已经执行成功。

图片来自于小林coding:
在这里插入图片描述

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

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

相关文章

LeetCode 1976.到达目的地的方案数:单源最短路的Dijkstra算法

【LetMeFly】1976.到达目的地的方案数&#xff1a;单源最短路的Dijkstra算法 力扣题目链接&#xff1a;https://leetcode.cn/problems/number-of-ways-to-arrive-at-destination/ 你在一个城市里&#xff0c;城市由 n 个路口组成&#xff0c;路口编号为 0 到 n - 1 &#xff…

使用vite创建一个vue3项目

创建一个vue3项目 1.使用命令npm create vuelatest来创建一个vue3项目&#xff0c;注意&#xff1a;官网说明了必须node版本是18及以上的&#xff0c;这边需要注意下 2.然后根据提示进入项目目录 先npm install安装依赖&#xff0c;然后npm run dev启动项目 大家可以看到&am…

Windows安装Go语言及VScode配置

最近搞自己的网站时突然想起来很多上学时的事&#xff0c;那会美国总统还是奥巴马&#xff0c;网页课教的是DreamWeaver跟Photoshop&#xff0c;其他语言像PHP、Java8、Python都有学一点&#xff0c;讲究一个所见即所得。虽然是信管专业那时和斌桑班长对新语言很感兴趣&#xf…

分享一个完全免费的GPT4站点,gpts也可以用

给大家分享一个完全免费的GPT4站点&#xff0c;gpts也可以用点击链接可用

【Leetcode】1588.所有奇数长度子数组的和

题目描述 思路 题目要求我们求解所有奇数长度数组的和。若暴力循环求解&#xff0c;时间复杂度过高。所以&#xff0c;我们可以采用前缀和优化。 如上图输入arr数组&#xff0c;sum[i]用于计算arr数组中前i个数的和。(在程序中&#xff0c;先给sum[0]赋值&#xff0c;等于arr[0…

小程序API能力集成指南——画布API汇总(三)

CanvasContext canvas 组件的绘图上下文。 方法如下&#xff08;2&#xff09;&#xff1a; arc CanvasContext.arc CanvasContext.arc(number x, number y, number r, number sAngle, number eAngle, boolean counterclockwise) 功能描述 创建一条弧线。 创建一个圆可…

android开发者工具,最新整理

一 Java相关 1.重载函数的签名(区别是否是重载函数) 答&#xff1a;方法名参数类型参数顺序(返回值不是) 2.finalize的工作原理 答&#xff1a;一旦垃圾收集器准备好释放对象占用的存储空间&#xff0c;它首先调用finalize()&#xff0c;而且只有在下一次垃圾收集过程中&#…

AlibabaCloud微服务:Linux 部署 Sentinel 流量控制

目录 一、实验 1.环境 2.Linux 部署 Sentinel 3. 微服务接入Sentinel配置 二、 问题 1.Linux本地启动Sentinel控制台 2.JDBC连接失败 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统软件版本IP备注Linuxopenjdk 1.8.0192.168.204.200 maven3.5.0nac…

【踩坑专栏】追根溯源,从Linux磁盘爆满排查故障:mycat2与navicat不兼容导致日志暴增

昨天遇到了一个比较奇怪的问题&#xff0c;就是在挂起虚拟机的时候&#xff0c;虚拟机提示我XX脚本正在运行&#xff0c;很奇怪&#xff0c;我没有运行脚本&#xff0c;为什么会提示我这个呢。今天恢复虚拟机&#xff0c;也提示了一下脚本的问题&#xff0c;而且发现Linux明显异…

关于制作Python游戏全过程(汇总1)

目录 前言: 1.plane_sprites模块: 1.1导入模块: 1.1.1pygame&#xff1a;一个用于创建游戏的Python库。 1.1.2random&#xff1a;Python标准库中的一个模块&#xff0c;用于生成随机数。 1.2定义事件代号: 1.2.1ENEMY_EVENT&#xff1a;自定义的敌机出场事件代号&#xf…

目标检测5:采用yolov8, RK3568上推理实时视频流

上一个效果图&#xff0c;海康球机对着电脑屏幕拍&#xff0c;清晰度不好。 RK3568接取RTSP视频流&#xff0c;通过解码&#xff0c;推理&#xff0c;编码&#xff0c;最终并把结果推出RTSP视频流。 数据集采用coco的80个种类集&#xff0c;通过从yovo8.pt&#xff0c;转换成R…

flutter开发文档,靠着这份面试题跟答案

1、知道它是什么、有什么用 相信很多人在学习的时候&#xff0c;一开始都会在网上找一整套资料或者买一本书来学习&#xff0c;结果就是内容太多&#xff0c;学了记不住或者学到一半感觉很难&#xff0c;便放弃了&#xff0c;更别提写代码了&#xff0c;根本无从入手。 而更好…

Python+Vue全栈开发BI数据可视化项目

如何得到这样一个大屏可视化展示 数据清洗&#xff0c;运算&#xff0c;建模&#xff0c;分析&#xff0c;可视化

java核心技术第十一章学习笔记

swing常用用户界面组件 Swing和模型-视图-控制器设计模式 模型&#xff1a;存储内容&#xff0c;必须实现改变内容和查找内容的方法&#xff0c;不可见 视图&#xff1a;显示内容 控制器&#xff1a;处理用户输入 一个模型可以有多个视图&#xff0c;每个视图可以显示全部…

微信小程序开发系列(十九)·wxml语法·setData()修改数据

目录 步骤一&#xff1a;创建一个data对象 步骤二&#xff1a;双大括号写法的使用 步骤三&#xff1a;创建一个更新事件按钮 步骤四&#xff1a;定义事件处理函数获取数据 步骤五&#xff1a;定义事件处理函数修改数据 方法一&#xff1a;通过赋值的方式直接修改数据 方…

android音视频编解码,你有过迷茫吗

3-5年的Android工程师最容易遇到的4个瓶颈是什么&#xff1f; 1.原理认知浅 工作内容多是简单UI界面开发和第三方SDK整合&#xff0c;对原理层和底层开发了解不深 2.技术视野窄 长期在小型软件公司&#xff0c;外包公司工作&#xff0c;技术视野被限制的太厉害 3.薪资提升…

React富文本编辑器开发(五)

到目前为止我们所有的功能操作都是直接写在 onKeydown 事件里了&#xff0c;但如果我想复用相同的功能怎么办呢&#xff0c;最好的办法就是拨离了&#xff0c;下面我就形如进行这样的操作&#xff0c;把相关的可复用的命令操作抽取出来。 新建文件 _helper.jsx,创建一个协助器…

游戏引擎渲染流程

一、渲染概述 我们首先看到渲染技术的发展 游戏渲染面临的挑战&#xff1a; 一个容器中同一时刻有大量的游戏对象需要进行渲染&#xff0c;并且不同对象渲染的形式、算法还有所差异&#xff0c;这些使得游戏的绘制系统变得非常复杂&#xff1b;其次&#xff0c;游戏引擎的渲染…

空间直角坐标系、大地坐标系、平面坐标系介绍

空间直角坐标系、大地坐标系、平面坐标系 2017-04-11 13:53 ( 一)空间直角坐标系 空间直角坐标系的坐标原点位于参考椭球的中心,Z轴指向参考椭球的北极,X轴指向起始子午面与赤道的交点,Y轴位于赤道面上切按右手系于X轴呈90度夹角,某点中的坐标可用该点在此坐标系的各…

如何分辨Mac设备X86或ARM

在终端中输入如下命令可以获取到当前 Mac 设备是 X86 还是 ARM 类型 uname -a 以上便是此次分享的全部内容&#xff0c;希望能对大家有所帮助!