MySQL(六):redo日志——保证事务的持久性

news2024/12/26 15:32:02

目录

  • 一、redo日志的基本介绍
    • 1.1 什么是redo日志
    • 1.2 redo日志的格式
    • 1.3 redo日志的类型
    • 1.4 Mini-Transaction
  • 二、redo日志的写入过程
    • 2.1 redo log block
    • 2.2 redo日志缓冲区
    • 2.3 将redo日志写入log buffer
    • 2.3 redo日志刷新到磁盘
    • 2.5 redo日志文件组
    • 2.6 redo日志文件格式
    • 2.7 log sequence number
    • 2.8 flushed_to_disk_lsn
    • 2.8 flush链表中的lsn
    • 2.9 checkpoint

一、redo日志的基本介绍

1.1 什么是redo日志

在真正访问页面之前,需要把在磁盘中的页加载到内存中的BufferPool中,之后才可以访问,现有如下场景,我们只在内存的BufferPool中修改了页面,假设在事务提交后突然发生了某个故障,导致内存中的数据都失效了,那么已提交的事务在数据库中所做的更改也就跟着丢失了,这是违背事务的持久性的。


就这个问题而言,大家可能想到的解决办法是,在事务提交之前,把事务修改过的所有页面都刷新到磁盘中,不过这个办法有下面几个缺陷:

  • 有时我们只是修改了某个页面中的一个字节,此时如果将整个页面都刷新到磁盘中就有些太浪费了
  • 随机I/O刷新起来很慢,一个事务可能会修改很多的页面,这些页面之间可能并不相邻,这就意味着在刷新时涉及很多的随机I/O。

redo日志给出的解决方法是,没必要每次在事务提交时就把事务在内存中的修改过的页面全部刷新到磁盘,只需把修改的内容记录下来就可以了,例如,某个事务将系统表空间的第99号页面中偏移量为1000处的字节从1改为0,然后在事务提交时,将该事务执行过程中产生的redo日志刷新到磁盘中就可以了。
使用redo日志的好处:

  • redo日志占用的空间更小,在redo日志中只需记录表空间ID,页号,偏移量,更新的数据
  • redo日志写入磁盘的过程是顺序I/O,因为某个事务产生的redo日志会按顺序放到相邻的页中

1.2 redo日志的格式

在这里插入图片描述
type:表示redo日志的类型
spaceID:表空间ID
page number:页号
data:redo日志的具体内容

1.3 redo日志的类型

  • MLOG_REC_INSERT:表示在插入一条使用非紧凑行格式(REDUNDANT)的记录时,redo日志的类型
  • MLOG_COMP_REC_INSERT type 字段对应的十进制数字为 38) 表示在插入一条使用紧凑行格式 COMPACT DYNAMIC OMPRESSED 的记录时 redo 日志的类型.
  • MLOG_COMP]AGE_CREATE (type 字段对应的十进制数字为 58) 表示在创建一个存储紧凑行格式记录的页面时 red 日志的类型.
  • MLOG_COMP_REC_DELETE type 字段对应的十进制数字为 42 ): 表示在删除一条使用紧凑行格式记录时 redo 日志的类型.

    redo日志的类型有很多,用到哪个在详细说

1.4 Mini-Transaction

一条insert语句可能修改很多的页面,比如系统表空间页号为7的页面的Max Row ID 属性,还可能修改聚簇索引和二级索引对应的B+树中的页面,在执行语句的过程中产生的redo日志,InnoDB将这些日志划分成了很多不可分割的组。

例如:

  • 向聚簇索引对应的B+树的页面插入一条记录产生的redo日志是一组的,是不可分割的
  • 向某个二级索引对应的B+树的页面插入一条记录时产生的redo日志也是一组的,是不可分割的

【为什么是不可分割的呢?】

以向某个索引对应的 树中插入一条记录为例进行解释,首先定位这条记录该被插入到的数据页
乐观情况:该数据页剩余空间充足,直接将要插入的记录插入到该页面中即可,产生一条redo日志
悲观情况:该数据页剩余空间不足,需要进行页分裂操作,然后把原先数据页中的记录复制到新的数据页中…等一系列操作下来会产生很多条的redo日志,这些redo日志就是不可分割的组
redo日志是为了在系统因崩溃而重启时恢复崩溃前的状态而提出的,如果在悲观插入的过程只记录了一部分redo日志,那么在按照这一部分redo日志恢复出的B+树会是一种不正确的状态,因此在执行需要保证原子性的操作时,必须一组的形式记录redo日志,在进行恢复时,针对某个组中的redo日志,要么全部恢复,要么一条都不恢复。

【这在MySQL中是怎么做到的呢?】

某个需要保证原子性的操作所产生 一系 redo 日志,必须以一条类型为 MLOG
MULTl_REC_END redo 志结尾这样在系统因崩溃而重启恢复时,只有解析到类型为 MLOG MULTl REC END redo日志时,才认为解析到了一组完整的 redo 才会进行恢复:否则直接放弃前面解析到的redo日志

二、redo日志的写入过程

2.1 redo log block

为了更好的管理redo日志,InnoDB把通过MTR生成的redo日志都放到了大小为512字节的中
在这里插入图片描述
log block header中几个属性的含义:
HDR_NO:每个block都有一个编号
HDR_DATA_LEN:表示当前block已经使用了多少个字节
FIRST_REC_GROUP:表示该block中第一个MTR生成的redo日志记录组的偏移量
CHECKPOINT_NO:checkpoint的序号

2.2 redo日志缓冲区

InnoDB为了解决磁盘速度过慢的问题引入了BufferPool,同理,写入redo日志时也不会直接写到磁盘中,在服务器启动时向操作系统申请了一大片连续的内存空间称为redo log buffer,这片内存空间被分为若干个连续的redo log block
在这里插入图片描述

2.3 将redo日志写入log buffer

向log buffer中写入redo 日志是顺序写入的,通过一个 buf_free的全局变量,指明后续写入的redo日志应该写到log buffer的哪个位置
在这里插入图片描述

2.3 redo日志刷新到磁盘

redo日志刷盘时机,redo日志总不能一直待在内存中,会在某些时机将redo日志刷新到磁盘中,具体有:

  • log buffer空间不足时,当redo日志占满log buffer的50%时,就需要将这些日志刷新到磁盘中
  • 事务提交时
  • 后台有一个线程,不断扫描log buffer,将redo日志刷新到磁盘
  • 正常关闭服务器时
  • 做checkpoint时

2.5 redo日志文件组

MySQL数据目录下默认有两个名为ib_logfile0和ig_logfile1的两个文件,log buffer默认刷新到这两个文件中。也就是说,redo日志文件不止一个,而是以日志文件组的形式出现: ib _logfile1 写满了就去 ib_logfile2; 依此类推.如果写到最后一个文件 , 时发现写满了,该咋办?那就重新转到 ib_logfile0继续写.
在这里插入图片描述

2.6 redo日志文件格式

redo日志文件也是由若干个512字节大小的block组成,
在redo日志文件组中,前2048(也就是前4个block)用来存储一些管理信息,后面的字节用来存储log buffer中的block镜像
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.7 log sequence number

log sequence number(lsn)是一个全局变量,记录当前总共已经写入的redo日志量,lsn的初始值是8704. 每一组由MTR生成的redo日志都有一个唯一的lsn值与其对应,lsn值越小,说明redo日志产生的越早

2.8 flushed_to_disk_lsn

flushed_to_disk_lsn也是一个全局变量,表示刷新到磁盘中的redo日志量,初始值也是8704,随着系统的运行,不断有redo日志产生,不断被写入到log buffer,但并不会立即刷新到磁盘,此时lsn和flushed_to_disk_lsn就产生差距了

在这里插入图片描述

2.8 flush链表中的lsn

在MTR执行过程中修改过的页会被加入到Buffer Pool的flush链表中,第一次修改某个已经加载到Buffer Pool中的页面时,就会把这个页面对应的控制块插入到flush链表的头部,之后再修伊该页面时,由于它已经在 f1 1 链表中, 不再
了.
的控制块中记录两个关于页面何时修改属性:

  • oldest_modification 第一次修改 Buffer Pool 中的某个缓冲页时, 就将修该页面MTR 开始时对应的lsn值写入这个属性
  • newest_modification 每修改一次页面,都会将修改该页面的 MTR 束时对
    lsn值写入这个属性.

2.9 checkpoint

由于redo日志文件组的容量是有限的,redo日志的作用是为了在系统崩溃后恢复脏页用的,如果对应的脏页已经刷新到磁盘中了,那么这些redo日志也就没有用了,因此判断redo日志占用的磁盘空间可不可以被覆盖的依据是,该redo日志对应的脏页有没有被刷新到磁盘中。
在InnoDB中,使用checkpoint_lsn表示当前系统中可以被覆盖的redo日志总量是多少,该变量的初始值是8704.
当页a被刷新到了磁盘上,那么此时操作页a时生成的redo日志就可以被覆盖了,然后进行一次增加check_point的操作,这个过程称为执行一次checkpoint

执行一次checkpoint分为两个步骤:

  1. 计算当前可以被覆盖的redo日志对应的lsn最大是多少
    首先找到flush链表的尾节点,找到该尾节点的oldest_modification,凡是小于该oldest_modification的lsn对应的日志都可以被覆盖掉,因为这些redo日志对应的被修改过的页面都已经刷新到内存中了

  2. 将checkpoint_lsn 与对应的 redo 日志文件组偏移 以及此次checkpoint的编号写到日志文件管理信息〈就是 checkpoint1或者 checkpoint2 )中。

【用户线程批量从flush链表中刷出脏页】

内容参考《MySQL是怎样运行的》

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

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

相关文章

【MySQL进阶】MySQL触发器详解

序号系列文章7【MySQL基础】运算符及相关函数详解8【MySQL基础】MySQL多表操作详解9【MySQL进阶】MySQL事务详解10【MySQL进阶】MySQL视图详解文章目录前言1,触发器1.1,触发器概述1.2,触发器使用环境2,触发器基本操作2.1&#xff…

CentOS7 安装单机 Kafka

一、单机安装 1、上传压缩文件到服务器、解压 tar -zxvf kafka_2.13-3.3.2.tgz -C /usr/local #解压到 usr/local目录下 进入解压目录下 更名kafka mv kafka_2.13-3.3.2/ kafka-3.3.2 2、配置环境变量 vim /etc/profile export KAFKA_HOME/usr/local/kafka-3.3.2export PATH$PA…

MySQL学习记录(9)InnoDB存储引擎

文章目录6、InnoDB存储引擎6.1、逻辑存储结构6.2、架构6.2.1、概述6.2.2、内存结构6.2.3、磁盘结构6.2.4、后台线程6.3、事务原理6.3.1、事务基础6.3.2、redo log日志6.3.3、undo log日志6.4、MVCC6.4.1、基本概念6.4.2、记录中隐藏字段6.4.3、undo log日志6.4.4、readview6.4.…

【Pytorch项目实战】之图像分类与识别:手写数字识别(MNIST)、普适物体识别(CIFAR-10)

文章目录图像分类与识别(一)实战:基于CNN的手写数字识别(数据集:MNIST)(二)实战:基于CNN的图像分类(数据集:CIFAR-10)图像分类与识别 …

Lua 函数 - 可变参数

Lua 函数 - 可变参数 参考至菜鸟教程。 Lua函数可以接收可变数目的参数,和C语言类似,在函数参数列表中使用三点...表示函数有可变的参数。 function add(...) local s 0 for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数…

模拟实现C库函数(2)

"烦恼无影踪,丢宇宙~"上一篇的模拟实现了好几个库函数,strlen\strcpy\memcpy\memmove,那么这一篇又会增加几个常用C库函数的模拟实现 memset\itoa\atoi。一、memsetmemset - fill memory with a constant byte#include <string.h>void *memset(void *s, int c,…

机器自动翻译古文拼音 - 十大宋词 - 江城子·乙卯正月二十日夜记梦 苏轼

江城子乙卯正月二十日夜记梦 宋苏轼 十年生死两茫茫&#xff0c;不思量&#xff0c;自难忘。 千里孤坟&#xff0c;无处话凄凉。 纵使相逢应不识&#xff0c;尘满面&#xff0c;鬓如霜。 夜来幽梦忽还乡&#xff0c;小轩窗&#xff0c;正梳妆。 相顾无言&#xff0c;惟有泪千…

uniapp使用及踩坑项目记录

环境准备 下载 HBuilderX 使用命令行创建项目&#xff1a; 一些常识准备 响应式单位rpx 当设计稿宽度为750px的时&#xff0c;1rpx1px。 uniapp中vue文件style不用添加scoped 打包成h5端的时候自动添加上去&#xff0c;打包成 微信小程序端 不需要添加 scoped。 图片的…

SpringDataJpa set()方法自动保存失效

问题描述&#xff1a;springdatajpa支持直接操作对象设置属性进行更新数据库记录的方式&#xff0c;正常情况下&#xff0c;get()得到的对象直接进行set后&#xff0c;即使不进行save操作&#xff0c;也将自动更新数据记录&#xff0c;将改动持久化到数据库中&#xff0c;但这里…

20230126使AIO-3568J开发板在原厂Android11下跑起来

20230126使AIO-3568J开发板在原厂Android11下跑起来 2023/1/26 18:22 1、前提 2、修改dts设备树 3、适配板子的dts 4、&#xff08;修改uboot&#xff09;编译系统烧入固件验证 前提 因源码是直接使用原厂的SDK&#xff0c;没有使用firefly配套的SDK源码&#xff0c;所以手上这…

Linux安装mongodb企业版集群(分片集群)

目录 一、mongodb分片集群三种角色 二、安装 1、准备工作 2、安装 configsvr配置 router配置 shard配置 三、测试 四、整合Springboot 一、mongodb分片集群三种角色 router角色&#xff1a; mongodb的路由&#xff0c;提供入口&#xff0c;使得分片集群对外透明&…

【目标检测论文解读复现NO.27】基于改进YOLOv5的螺纹钢表面缺陷检测

前言此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0c;…

【工程化之路】Node require 正解

require 实现原理 流程概述 步骤1&#xff1a;尝试执行代码require("./1"). 开始调用方法require.步骤2&#xff1a;此时会得到filename&#xff0c;根据filename 会判断缓存中是否已经加载模块&#xff0c;如果加载完毕直接返回&#xff0c;反之继续执行步骤3&…

python图像处理(laplacian算子)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 和之前的prewitt算子、sobel算子不同,laplacian算子更适合检测一些孤立点、短线段的边缘。因此,它对噪声比较敏感,输入的图像一定要做好噪声的处理工作。同时,laplacian算子设计…

Leetcode 03. 无重复字符的最长子串 [C语言]

目录题目思路1代码1结果1思路2代码2结果2该文章只是用于记录考研复试刷题题目 Leetcode 03: 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所…

尚医通-OAuth2-微信登录接口开发(三十一)

目录&#xff1a; &#xff08;1&#xff09;微信登录-OAuth2介绍 &#xff08;2&#xff09;前台用户系统-微信登录-准备工作 &#xff08;3&#xff09;微信登录-生成微信二维码-接口开发 &#xff08;4&#xff09;微信登录-生成验证码-前端整合 &#xff08;5&#xf…

Telerik DevCraft Ultimate R1 2023

Telerik DevCraft Ultimate R1 2023 Kendo UI R1 2023-添加新的Chip和ChipList组件。 KendoReact R1 2023&#xff08;v5.11.0&#xff09;-新的PDFViewer组件允许用户直接在应用程序中查看PDF文档。 Telerik JustLock R1 2023-Visual Studio快速操作菜单现在可以在创建通用…

蓝桥杯重点(C/C++)(随时更新,更新时间:2023.1.29)

点关注不迷路&#xff0c;欢迎推荐给更多人 目录 1 技巧 1.1 取消同步&#xff08;节约时间&#xff0c;甚至能多骗点分&#xff0c;最好每个程序都写上&#xff09; 1.2 万能库&#xff08;可能会耽误编译时间&#xff0c;但是省脑子&#xff09; 1.3 蓝桥杯return 0…

【数据库-通用知识系列-01】数据库规范化设计之范式,让数据库表看起来更专业

我们在设计数据库时考虑的因素包括读取性能&#xff0c;数据一致性&#xff0c;数据冗余度&#xff0c;可扩展性等&#xff0c;好好学习数据库规范化的知识&#xff0c;设计的数据库表看起来才专业。 范式一览 “键”理解&#xff1a; 超键&#xff1a;在关系中能唯一标识元组…

送什么礼物给小学生比较有纪念意义?适合送小学生的小礼物

送给小学生的礼物哪种比较有意义呢&#xff1f;送给学生的礼物&#xff0c;基本上是对学习有所帮助的&#xff0c;但是像送钢笔、练习册这些&#xff0c;有一部分学生是抗拒的&#xff0c;作为大人就是希望对视力、对成长有用的东西&#xff0c;我认为保护视力是现在许多家庭的…