Mysql redolog

news2024/12/23 17:32:18

一、redolog 是啥

数据库的ACID:A原子性,C一致性,I隔离性,D持久性;

redolog:保证 持久性;

redolog: 系统奔溃重启时需要按照上述内容所记录的步骤重新更新数据页,特点:

1、redo 日志占用空间非常小:存储表空间ID、页号、偏移量以及需要更新的值所需的存储空间。

2、redo 日志顺序写入磁盘:执行事务时,产生若干条 redo 日志,按顺序写入磁盘,顺序IO。

二、redlog日志格式

type:该条 redo 日志的类型。
space ID:表空间ID。 
page number:页号。 
data:该条 redo 日志的具体内容。

三、乐观插入与悲观插入

悲观插入:产生页分裂,一条数据插入会产生多条redlog,最后一条必须以一个特殊的redolog结尾MLOG_MULTI_REC_END,type 字 段对应的十进制数字为 31。

 四、Mini-Transaction的概念

把对底层页面中的一次原子访问的过程称之为一个 Mini-Transaction ,简称 mtr。比如:向某个索引对应的 B+ 树中插入一条记录的过程 也算是一个 Mini-Transaction 。一个所谓的 mtr 可以包含一组 redo 日志,在进 行奔溃恢复时这一组 redo 日志作为一个不可分割的整体。

五、redo日志的写入过程 

5.1 redo log block

通过 mtr 生成的 redo 日志都放在了大小为 512字节 的页中。为了和我们前边提到的表空间中的页做区别,我们这里把用来存储 redo 日志的页称为 block。

log block header 的几个属性的意思分别如下:
1、LOG_BLOCK_HDR_NO:每一个block都有一个大于0的唯一标号,本属性就表示该标号值。
2、LOG_BLOCK_HDR_DATA_LEN :表示block中已经使用了多少字节,初始值为 12 (因为 log block body 从第12个字节处开始)。随着往block中写入的redo日志越来也多,本属性值也跟着增长。如果 log block body已经被全部写满,那么本属性的值被设置为 512 。
3、LOG_BLOCK_FIRST_REC_GROUP :一条 redo 日志也可以称之为一条 redo 日志记录( redo log record ),一个 mtr 会生产多条 redo 日志记录,这些 redo 日志记录被称之为一个 redo 日志记录组( redo logrecord group )。 LOG_BLOCK_FIRST_REC_GROUP 就代表该block中第一个 mtr 生成的 redo 日志记录组的偏移量(其实也就是这个block里第一个 mtr 生成的第一条 redo 日志的偏移量)。
4、LOG_BLOCK_CHECKPOINT_NO :表示所谓的 checkpoint 的序号.
log block trailer 中属性的意思如下:
LOG_BLOCK_CHECKSUM :表示block的校验值,用于正确性校验,我们暂时不关心它。

5.2 redo log buffer

写入 redo 日 志时也不能直接直接写到磁盘上,实际上在服务器启动时就向操作系统申请了一大片称之为 redo log buffer 的 连续内存空间,参数innodb_log_buffer_size(默认16M)。结构如下:

 5.3 redo log 写入log buffer

log buffer 中写入 redo 日志的过程是顺序的,需要知道下一个往哪个block(页?)中写。

buf_free:该变量指明后 续写入的 redo 日志应该写入到 log buffer 中的哪个位置:

一个 mtr 执行过程中可能产生若干条 redo 日志,这些 redo 日志是一个不可分割的组,每个 mtr 运行过程中产生的日志先暂时存到 一个地方,当该 mtr 结束的时候,将过程中产生的一组 redo 日志再全部复制到 log buffer 中。我们现在假设 有两个名为 T1 、 T2 的事务,每个事务都包含2个 mtr ,我们给这几个 mtr 命名一下: 

        事务 T1 的两个 mtr 分别称为 mtr_T1_1 和 mtr_T1_2 。

        事务 T2 的两个 mtr 分别称为 mtr_T2_1 和 mtr_T2_2 。

每个 mtr 都会产生一组 redo 日志,用示意图来描述一下这些 mtr 产生的日志情况:

不同的事务可能是并发执行的,所以 T1 、 T2 之间的 mtr 可能是交替执行。每当一个 mtr 执行完成时,伴随该 mtr 生成的一组 redo 日志就需要被复制到 log buffer 中,也就是说不同事务的 mtr 可能是交替写入 log buffer 的,我们画个示意图:

不同的 mtr 产生的一组 redo 日志占用的存储空间可能不一样,有的 mtr 产生的 redo 日志量很少,比如 mtr_t1_1 、 mtr_t2_1 就被放到同一个block中存储,有的 mtr 产生的 redo 日志量非常 大,比如 mtr_t1_2 产生的 redo 日志甚至占用了3个block来存储。 

五 redolog File

5.1 redolog buffer 刷盘时机

1、log buffer 空间不足时:log buffer 的 redo 日志量已经占满了 log buffer 总容量的大约一半左右,就需要把这些日志刷新到磁盘上。(通过系统变量 innodb_log_buffer_size 指定)

2、事务提交时:保证持久性,必须要把修改这些页面对应的 redo 日志刷新到 磁盘。

3、后台线程不停的刷:大约每秒都会刷新一次 log buffer 中的 redo 日志到磁盘。

4、正常关闭服务器时和 checkpoint 时

5.2 redo日志文件组

log buffer默认刷新到ib_logfile0和ib_logfile1两个文件中,

innodb_log_group_home_dir:ib_logfile0和ib_logfile1文件目录。

innodb_log_file_size:两个文件大小,默认值为 48MB 。

innodb_log_files_in_group:redo 日志文件的个数,默认值为2,最大值为100。

写入日志组过程

在将 redo 日志写入 日志文件组时,从 ib_logfile0 开始写,如果 ib_logfile0 写满了,就接着 ib_logfile1 写,ib_logfile1 写满了就去 写 ib_logfile2 ,依此类推。如果写到最后一个文件该咋办?那就重新转到 ib_logfile0 继续写;

5.3 redo log文件格式
****log buffer中的redo日志刷新到磁盘的本质,就是把block的镜像写入日志文件中 ****,redo 日志文件其实也是由若干 个 512 字节大小的block组成:
        前2048个字节,也就是前4个block是用来存储一些管理信息的。 
        从第2048字节往后是用来存储 log buffer 中的block镜像的。

 5.3 Log Sequeue Number(LSN)

lsn: 记录已经写入的 redo 日志量(日志序列号),初始的 lsn 值为 8704;数据写入示例如下:

5.3.1 初始启动时(8704+增长值)

系统第一次启动后初始化 log buffer 时, buf_free (就是标记下一条 redo 日志应该写入到 log buffer 的位置的变量)就会指向第一个 block 的偏移量为12字节( log block header 的大小)的地方,那么 lsn 值也会跟着增加12:

5.3.2 剩余空间够用时(直接加法操作)

如果某个 mtr 产生的一组 redo 日志占用的存储空间比较小,待插入的block剩余空闲空间能容纳这 个 mtr 提交的日志时, lsn 增长的量就是该 mtr 生成的 redo 日志占用的字节数,就像这样:

假设上图中 mtr_1 产生的 redo 日志量为200字节,lsn 就要在 8716 的基础上增加 200 ,为 8916

5.3.3 剩余空间不足时(额外加上 log block header,log block trailer)

如果某个 mtr 产生的一组 redo 日志占用的存储空间比较大,也就是待插入的block剩余空闲空间不足以容纳 这个 mtr 提交的日志时, lsn 增长的量就是该 mtr 生成的 redo 日志占用的字节数加上额外占用的 log block header 和 log block trailer 的字节数,就像这样:

我们假设上图中 mtr_2 产生的 redo 日志量为1000字节,为了将 mtr_2 产生的 redo 日志写入 log buffer ,我们不得不额外多分配两个block,所以 lsn 的值需要在 8916 的基础上增加 1000 + 12×2 + 4 × 2 = 1032 

5.4 flushed_to_disk_lsn

buf_next_to_write:记录log buffer中哪些被刷盘(刷盘之前先写到log buffer)。

5.5 lsn值和redo日志文件偏移量的对应关系

初始时的 LSN 值是 8704 ,对应文件偏移量 2048 ,之后每个 mtr 向磁盘中写入多少字节日志, lsn 的值就增长 多少。

 5.6 flush链表中的LSN和mtr作用

5.6.1 mtr作用

1、可能会产生一组不可分割的 redo 日志,在mtr结束时,会把这一组 redo 日志写入到 log buffer 
2、把在mtr执行过程中可能修改过的页面加入到Buffer Pool的flush链表

5.6.2 flush更新lsn过程

oldest_modification :如果某个页面被加载到 Buffer Pool 后进行第一次修改,那么就将修改该页面的 mtr 开始时对应的 lsn 值写入这个属性。

newest_modification :每修改一次页面,都会将修改该页面的 mtr 结束时对应的 lsn 值写入这个属性。 也就是说该属性表示页面最近一次修改后对应的系统 lsn 值。 

页面写入过程示意图:

flush链表中的脏页按修改发生的时间顺序进行排序,按照 oldest_modification代表的LSN值进行排序,被多次更新的页面不会重复插入到flush链表中,但会更新 newest_modification属性值。 

5.7 checkpoint 和checkpoint_lsn

5.7.1 存在的意义

判断某些redo log占用的磁盘空间是否可以覆盖的依据就是它对应的脏页是否已经刷新到磁盘里。

flush链表,log buffer,log file 日志写入示意图:

如图,虽然 mtr_1 和 mtr_2 生成的 redo 日志都已经被写到了磁盘上,但是它们修改的脏页仍然留在 Buffer Pool 中,所以它们生成的 redo 日志在磁盘上的空间是不可以被覆盖的。之后随着系统的运行,如果 页a 被刷新 到了磁盘,那么它对应的控制块就会从 flush链表 中移除,就像这样子: 

 5.7.2 checkpoint_lsn

 代表当前系统中可以被覆盖的 redo 日志总量是多少,这个变量初始值也是 8704。页a 被刷新到磁盘, mtr_1 生成的 redo 日志就可以被覆盖,所以我们可以进行一个增加 checkpoint_lsn 的操作,我们把这个过程称之为做一次 checkpoint。步骤如下:

1、计算一下当前系统中可以被覆盖的 redo 日志对应的 lsn 值最大是多少。

redo 日志可以被覆盖,意味着它对应的脏页被刷到了磁盘,只要我们计算出当前系统中被最早修改的脏页 对应的 oldest_modification 值,那凡是在系统lsn值小于该节点的oldest_modification值时产生的redo日志 都是可以被覆盖掉的,我们就把该脏页的 oldest_modification 赋值给 checkpoint_lsn 。 比方说当前系统中 页a 已经被刷新到磁盘,那么 flush链表 的尾节点就是 页c ,该节点就是当前系统中最 早修改的脏页了,它的 oldest_modification 值为8916,我们就把8916赋值给 checkpoint_lsn (也就是说 在redo日志对应的lsn值小于8916时就可以被覆盖掉)。

2、checkpoint_lsn 和对应的 redo 日志文件组偏移量以及此次 checkpint 的编号写到日志文件的 管理信息(就是 checkpoint1 或者 checkpoint2 )中。

5.8 innodb_flush_log_at_trx_commit的用法 

0: 事务提交时,每次都会写入logbuffer ,但是只会定时(每秒)写入(调用fsync)osbuffer ,在写入到磁盘文件,可能会丢失1 秒内的数据。
1: mysql默认规则,事务提交时每次都写入 logbuffer、osbuffer、刷新到磁盘。数据完整性能低。
2: 事务提交时每次都写入osbuffer,但是每秒执行一次写入磁盘操作。

5.9 奔溃恢复

5.9.1 奔溃恢复起点

对于 checkpoint_lsn 之后的 redo 日志,它 们对应的脏页可能没被刷盘,也可能被刷盘了,我们不能确定,所以需要从 checkpoint_lsn 开始读取 redo 日志 来恢复页面。要把 checkpoint1 checkpoint2 这两个block中的 checkpoint_no 值读出来比一下大小,哪个的 checkpoint_no 值更大,说明哪个block存储的就是最近的一次 checkpoint 信息。这样我们就能拿到最近发生 的 checkpoint 对应的 checkpoint_lsn 值以及它在 redo 日志文件组中的偏移量 checkpoint_offset

5.9.2 确定恢复的终点

根据block扫描到最后一个block(没写满的block)

5.9.3 怎么恢复

根据 redo 日志的 space ID 和 page number 属性计算出散列值,把 space ID 和 page number 相同的 redo 日志放到哈希表的同一个槽里,如果有多个 space ID 和 page number 都相同的 redo 日志,那么它们之间 使用链表连接起来,按照生成的先后顺序链接起来的

同一个页面进行修改的 redo 日志都放在了一个槽里,所以可以一次性将一 个页面修复好(避免了很多读取页面的随机IO),这样可以加快恢复速度。另外需要注意一点的是,同一个 页面的 redo 日志是按照生成时间顺序进行排序的,所以恢复的时候也是按照这个顺序进行恢复,如果不按 照生成时间顺序进行排序的话,那么可能出现错误。比如原先的修改操作是先插入一条记录,再删除该条记 录,如果恢复时不按照这个顺序来,就可能变成先删除一条记录,再插入一条记录,这显然是错误的。

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

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

相关文章

微服务架构七种模式

微服务架构七种模式 目录概述需求: 设计思路实现思路分析 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challenge Survive.…

软件架构设计(三) B/S架构风格-层次架构(一)

层次架构风格从之前的两层C/S到三层C/S,然后演化为三层B/S架构,三层B/S架构之后仍然在往后面演化,我们来看一下层次架构演化过程中都有了哪些演化的架构风格呢? 而我们先简单了解一下之前的层次架构风格中分层的各个层次的作用。 表现层:由于用户进行交互,比如MVC,MVP,…

iOS脱壳之frida-ios-dump

frida-ios-dump介绍 该工具基于frida提供的强大功能通过注入js实现内存dump然后通过python自动拷贝到电脑生成ipa文件,适合现iOS11版本之后的越狱手机使用。 下载 https://github.com/AloneMonkey/frida-ios-dump环境安装 电脑环境安装 win和Mac 环境一样都是…

Metinfo6.0.0任意文件读取漏洞复现

漏洞原理 在\MetInfo6.0.0\app\system\include\module\的old_thumb.class.php文件 可以看到这里对./进行了严格的过滤,但是却忽略了在Windows下还可以用…\来跳转目录 环境搭建 下载Metinfo6.0.0 配置随便写,自己记住就行 这里前面已经审计过代码了&a…

linux离线环境安装redis

先检查gcc版本,使用gcc --version进行检查,版本在5以下的,安装redis要安装redis6以下的版本 如果没有gcc命令,要先安装gcc命令。因为是离线环境,yum命令什么的用不了。为了安装gcc,进行了几种尝试。 1、下…

Java设计模式:四、行为型模式-06:观察者模式

文章目录 一、定义:观察者模式二、模拟场景:观察者模式2.1 观察者模式2.2 引入依赖2.3 工程结构2.4 模拟摇号2.4.1 摇号服务接口2.4.2 摇号返回结果类 三、违背方案:观察者模式3.0 引入依赖3.1 工程结构3.2 添加摇号接口和实现3.2.1 摇号服务…

Nuxt 菜鸟入门学习笔记五:CSS 样式

文章目录 本地样式表在组件内导入通过 Nuxt 配置 CSS 属性导入使用字体导入通过 NPM 发布的样式表 外部样式表动态添加样式表【高级】使用 Nitro 插件修改渲染的头部 使用预处理器单文件组件 SFC 样式类和样式绑定使用 v-bind 的动态样式Scoped StylesCSS Modules预处理器支持 …

vue3中axios的使用方法

在Vue 3中使用axios发送HTTP请求的方法与Vue 2中基本相同。首先,需要安装axios库: npm install axios然后,在Vue组件中引入axios: import axios from axios;接下来,可以在Vue组件的方法中使用axios发送HTTP请求。例如…

基于金豺算法优化的BP神经网络(预测应用) - 附代码

基于金豺算法优化的BP神经网络(预测应用) - 附代码 文章目录 基于金豺算法优化的BP神经网络(预测应用) - 附代码1.数据介绍2.金豺优化BP神经网络2.1 BP神经网络参数设置2.2 金豺算法应用 4.测试结果:5.Matlab代码 摘要…

USRP 简介,对于NI软件无线电你所需要了解的一切

什么是 USRP 通用软件无线电外设( USRP ) 是由 Ettus Research 及其母公司National Instruments设计和销售的一系列软件定义无线电。USRP 产品系列由Matt Ettus领导的团队开发,被研究实验室、大学和业余爱好者广泛使用。 大多数 USRP 通过以太网线连接到主机&…

创建聊天机器人:产品专属ChatGPT智能问答机器人,可添加任意网站

ChatGPT智能问答机器人可以广泛应用于各种SaaS产品,通过创建聊天机器人可以快速反馈用户,并且针对性的提供解决方案,非常高效的完成客户问答反馈。 聊天机器人是生活中常见的一种交互方式,机器人根据用户输入的关键字,…

怎么提取视频中的音乐保存到本地?其实方法很简单

当你想要使用视频中的音乐时,你可以考虑将它从视频中提取出来。这可以用于制作音频样本集,制作铃声或其他音频素材,或者向其他人展示视频的音乐部分而无需显示视频本身。如果你是一位音乐制作人员,你可能会需要一些特定类型的音效…

监听页面异常 + 监听页面跳转 +监听页面销毁 :监听并记录当前页面停留的时间

首先描述一下应用场景:播放视频,记录观看时长(移动端左划动,右滑动,页面跳转,页面销毁[页面销毁主要是指使用中控台直接销毁]) 说一下我的思路: 1.长链接 : 使用websocket来实现&…

鲁棒优化入门(7)—Matlab+Yalmip两阶段鲁棒优化通用编程指南(下)

0.引言 上一篇博客介绍了使用Yalmip工具箱求解单阶段鲁棒优化的方法。这篇文章将和大家一起继续研究如何使用Yalmip工具箱求解两阶段鲁棒优化(默认看到这篇博客时已经有一定的基础了,如果没有可以看看我专栏里的其他文章)。关于两阶段鲁棒优化与列与约束生成算法的原…

1654. 到家的最少跳跃次数

文章目录 Tag题目来源题目解读解题思路实现细节实现代码复杂度分析 写在最后 Tag 【广搜】【上限证明】【图论】 题目来源 1654. 到家的最少跳跃次数. 题目解读 找到从位置 0 跳跃到位置 x 的最小跳跃次数,跳跃规则如下: 前进方向跳 a 个位置&…

OJ练习第156题——带因子的二叉树

带因子的二叉树 力扣链接:823. 带因子的二叉树 题目描述 给出一个含有不重复整数元素的数组 arr ,每个整数 arr[i] 均大于 1。 用这些整数来构建二叉树,每个整数可以使用任意次数。其中:每个非叶结点的值应等于它的两个子结点…

LC315. 计算右侧小于当前元素的个数(归并排序 - java)

计算右侧小于当前元素的个数 题目描述归并排序代码演示: 上期经典 题目描述 难度 - 困难 原题链接 - 计算右侧小于当前元素的个数 给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums…

【OJ比赛日历】快周末了,不来一场比赛吗? #09.03-09.09 #12场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…)比赛。本账号会推送最新的比赛消息,欢迎关注! 以下信息仅供参考,以比赛官网为准 目录 2023-09-03(周日) #5场比赛2023-09-04…

代码随想录笔记--字符串篇

目录 1--反转字符串 2--反转字符串II 3--反转字符串中的单词 4--KMP算法 5--重复的子字符串 1--反转字符串 主要思路&#xff1a; 双指针算法&#xff0c;交换两个指针的字符&#xff1b; #include <iostream> #include <vector>class Solution { public:void…

Unity ShaderGraph教程——进阶shader

1.水面&#xff08;一&#xff09; 公式&#xff1a;场景深度 节点深度 — 屏幕空间位置的W向量 半透明物体与不透明物体的相交边缘 原理&#xff1a;场景深度 节点深度包含透明像素&#xff0c;屏幕空间w向量不包含透明像素。 注意&#xff1a;需要在UniversalRP-xxxQuali…