前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >说到做到的redo日志

说到做到的redo日志

作者头像
热心的大肚皮
发布于 2023-02-28 06:01:31
发布于 2023-02-28 06:01:31
3060
举报

大家好,我是热心的大肚皮,皮哥。

Mini-Transaction

首先说下Mini-Transaction,对底层页面进行一次原子访问的过程叫Mini-Transaction(MTR)。一个事务包含多条语句,一条语句包含多个MTR,每个MTR包含多条redo日志。如下所示:

redo日志的写入

redo log block

为了更好的管理,MTR生成的redo日志都在大小为512字节的页中,也叫block,具体如下图:

log block header:block头信息,包含以下几个字段。

  • log_block_hdr_no:block编号。
  • log_block_hdr_data_len:已使用的字节数。
  • log_block_first_rec_group:每个MTR生成的redo日志叫一个redo日志记录组,这个属性代表该block中第一个MTR生成的redo日志记录组的偏移量,也就是这个block中第一个MTR生成的第一条redo日志的偏移量。
  • log_block_check_point_no:checkpoint序号。

log block body:redo日志存储的地方。

log block trailer:block尾信息。

  • log_block_checksum:block的校验值。

redo log 日志缓冲区

前面说过为了提高性能引入了Buffer Pool。同理,写redo日志时也是申请了一大片内存空间称为redo log buffer(redo日志缓冲区)也叫log buffer。

redo log 刷盘时机

  • redo log buffer空间不足时。log buffer使用了50%时,就会进行刷盘。
  • 事务提交时。
  • 后台线程,每秒一次的频率刷redo日志。
  • 正常关闭服务器
  • 做checkpoint时。

redo 日志文件格式

redo log buffer是若干个512字节的block,redo日志文件也是多个512字节大小的block组成,redo日志文件是循环利用的,也就是说最后一个写完,会在写第一个文件。5.7.22的版本默认的大小是48MB。在redo日志文件组中,每个文件的大小格式都一样。分别是:

  • 前2048个字节存储管理信息。
  • 从2048往后存储log buffer中的block镜像。

log buffer中的block镜像就不过多介绍了。这里只介绍每个redo日志文件的前2048个字节。如图。

log sequence number

全局变量log sequence number简称lsn,用来记录总共写入的redo日志量,默认值8704。向log buffer中写入redo日志时是以MTR生成的一组redo日志为单位写入。

flushed_to_disk_lsn

上面说过,lsn是记录写入缓冲区的全局变量,而flushed_to_disk_lsn是记录写入磁盘的全局变量,初始值也是8704。大家还记得之前说过的buffer pool中的flush链表吗?修改后,flush链表中的节点会用oldest_modification与newest_modification分别存储此次修改的flushed_to_disk_lsn开始值与结束值,而且flush链表最后修改的脏页会放到链表头部。

checkpoint

redo日志文件组的容量是有限的,所以不得不循环使用,那么如果发生追尾怎么办呢?为了复用,如果mtr_1的redo日志被刷到了磁盘上,那么这个redo日志就可以被覆盖,同时增加一个checkpoint_lsn的操作,这个过程叫执行一次checkpoint。具体的步骤如下。

  1. 计算可以被覆盖的redo日志对应的lsn最大是多少。通过flush链表中的最早修改的脏页的oldest_modification,来判断刷新到了哪里,把oldest_modification写到checkpoint_lsn。
  2. 将checkpoint_lsn与对应的redo日志文件组的偏移量以及checkpoint编号写到文件的管理信息中,也就是checkpoint1与checkpoint2,checkpoint_no是偶数时写checkpoint1中,反之checkpoint2中。

崩溃的话如何恢复呢?

服务器正常的情况下,redo基本上没什么作用,但是一旦数据库出现问题,在重启时redo日志可以将页面恢复到系统崩溃前的状态。

  • 确定恢复的起点

lsn不小于checkpoint中checkpoint_lsn的redo日志,这以后的redo日志不确定是否刷盘,通过比较checkpoint1与checkpoint2的checkpoint_no大小来获取checkpoint_lsn与checkpoint_offset,以此定位从哪里开始。

  • 确定恢复的终点

前面说过redo日志是顺序写入的,log block header有个LOG_BLOCK_HDR_DATA_LEN的属性,如果当前block填满了,则为512,反之不为512,所以终点也就是不为512的block。

  • 怎么恢复

首先使用哈希表,根据redo日志中的space ID 和page number属性计算出哈希值,将同一个space ID 和page number的日志放到同一个槽中,如果出现哈希冲突的话,使用链表链接起来,根据生成的先后顺序连接。

如果遇到已经刷新过的页面,则跳过,判断方式是根据页面中File Header中FIL_PAGE_LSN的属性。FIL_PAGE_LSN记录了最近一次修改页面时对应的lsn值(也就是页面控制块的newest_modification)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿日常笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Redo日志 (4)—log sequence number(六十二)
前面说了redo日志的格式,刷新到磁盘后台有线程每秒运行一次,还有事务提交的时候,buffer pool不会刷新到磁盘,但是log buffer会刷新到磁盘。Log buffer会分成若干的block,吧这些block持久化到磁盘上,mysql根目录有两个log_file0和log_file1,可以增加,当存满的时候,从0循环继续存储,默认是48Mb。每个block是512个字节,前面四个block占比2048个字节是记录管理信息,2048字节后面开始记录block。
用户9919783
2022/07/29
5590
MySQL——redo日志
在执行事务的过程中,每执行一条语句,就可能产生若干条redo日志,这些日志是按照产生的顺序写入磁盘的,也就是使用顺序I/O。
爪哇缪斯
2023/05/10
1K0
MySQL——redo日志
【MySQL系列】- Redo log知多少
InnoDB 存储引擎是以页为单位来管理存储空间的,我们的增删改查本质上都是对页面上进行操作。我们知道在访问磁盘的时候,MySQL是会把数据加载到Buffer Pool然后进行操作的。对于DML操作,表、索引等的增删改DDL操作,还有数据本身是在Buffer Pool缓冲池中可能还没来得及刷新到磁盘中,系统或者服务器突然崩溃,那这些数据该怎么恢复呢?
索码理
2022/09/20
5390
【MySQL系列】- Redo log知多少
Redo日志 (5)—mysql进阶(六十三)
前面说了lsn值就是log sequence number代表记录redo日志存了多少字节,默认值是8000多,算偏移量直接减一下就好,还有flush_to_disk的lsn值,这个值之前的数据代表都已经持久化,这个持久化代表redo日志持久化,但是对应的buffer pool数据还不能覆盖,这时候又checkpoint lsn值,这个值之前的数据都代表已经持久化完毕,是可以覆盖的。因为redo日志存储有限,存满之后,又会从第一个文件循环存储。可以用show engine innoDB status查看。
用户9919783
2022/07/29
2590
简单聊聊Innodb崩溃恢复那些事
本文想用简单精炼的语言将Innodb崩溃恢复那些事情好好拾到拾到,本文主要参考以下三本书和我个人一些感想而作:
大忽悠爱学习
2023/10/11
6730
简单聊聊Innodb崩溃恢复那些事
MySQL8.0 redo日志系统优化
现在主流的数据库系统的故障恢复逻辑都是基于经典的ARIES协议,也就是基于undo日志+redo日志的来进行故障恢复。redo日志是物理日志,一般采用WAL(Write-Ahead-Logging)机制,所以也称redo日志为wal日志,redo日志记录了所有数据的变更,undo日志是逻辑日志,记录了所有操作的前镜像,方便异常时进行回滚。用户在提交事务时,只要确保写redo日志成功即可,并不需要对应的数据页也实时落盘,这套机制的基本思想是利用空间换时间,用户事务的更新实际上在数据页和redo日志中记录了两份,传统的数据库存储引擎都是基于B+Tree来组织数据页,因此刷数据页是离散小块IO,而写redo是顺序IO,对磁盘介质更友好,而且OLTP场景下,业务对RT(ResponseTime)也比较敏感,所以这套机制非常流行。
星哥玩云
2022/08/18
5460
MySQL8.0 redo日志系统优化
MySQL中的Redo Log(三)
关于MySQL的redo log,之前写过两篇文章,都比较简短易懂,开始今天的内容之前,先贴一下前两篇的链接:
AsiaYe
2020/02/26
8380
🍑 MySQL事务日志 redo log 详解:
Innodb存储引擎是以页为单位来管理存储空间的。在真正访问页面之前,需要把在磁盘上的页缓存到内存中的Buffer Pool之后才可以访问。所有的变更都必须先更新缓冲池中的数据,然后缓冲池中的脏页会以一定的频率被刷入磁盘(Check Point机制),通过缓冲池来优化CPU和磁盘之间的鸿沟,这样就可以保证整体的性能不会下降太快。
爱吃糖的范同学
2023/02/15
2K0
【MySQL (六) | 详细分析MySQL事务日志redo log】
为了最大程度避免数据写入时 IO 瓶颈带来的性能问题,MySQL 采用了这样一种缓存机制:
周三不加班
2019/09/03
3.4K0
【MySQL (六) | 详细分析MySQL事务日志redo log】
Innodb buffer pool的flush链表
《MySQL8.0的redo log优化》一文中,我们介绍了MySQL8.0对redo log 的优化方式,其中有一条是脏页有序加入到flush_list的优化。今天我们来看看flush_list的概念,并解释下这个优化规则。
AsiaYe
2020/07/29
1.3K0
Innodb buffer pool的flush链表
redo日志文件格式(3)—mysql进阶(六十一)
前面我们说了修改一条数据总不能吧16kb的页全部持久化到磁盘上,于是有了redo日志,记录哪些修改的数据,redo日志也有自己的缓存区,并不是直接把数据记录到磁盘上,缓存区是innoDB_redo_buffer_size,默认是16mb,为了保证原子性,他会分为不同的组,当乐观插入的时候,只有一条数据需要插入,则type的第一个字节是1,代表只有一条插入,当悲观插入多条插入的时候,会有一个MLOG_MULTI_REC_END的日志,表示这组记录完毕,若系统宕机重启,解析redo日志时候,没有解析到这个,则前面解析的全部放弃。
用户9919783
2022/07/29
5010
浅析 InnoDB Redo Log
| 作者:陈俊熹,腾讯云数据库研发工程师,主要负责腾讯云MySQL数据库研发工作。 ---- 导语:之前的文章(见本文末)已经介绍了 InnoDB 的部分内外存数据结构,我也在学习过程中对 InnoDB 的一些数据对象有了基本认识,后面的文章会从数据流出发来学习 InnoDB。这篇文章主要学习 InnoDB Redo Log 的流程。Redo Log 是 InnoDB 实现数据一致性和持久化存储的关键,本文主要从设计原理和部分源码实现出发,对其中的知识点进行归纳总结。 1 Redo Log Buffer
腾讯云数据库 TencentDB
2020/02/14
1.3K0
浅析 InnoDB Redo Log
第14章_MySQL事务日志
🧑个人简介:大家好,我是 shark-Gao,一个想要与大家共同进步的男人😉😉
程序员Leo
2023/08/02
2590
第14章_MySQL事务日志
MySQL-8.0 redo优化剖析
提示:公众号展示代码会自动折行,建议横屏阅读 前言 redo_log的作用设计初衷为了提高写入性能同时解决ACID中Duration。MySQL 8.0对redo_log进行了无锁化设计,去除了redo_log性能的瓶颈,从而在数据库整体性能上有了较大提升。本文将结合已有资料和最新MySQL release代码,介绍MySQL redo log优化,主要设计模块包括redo_log、mtr和一部分buffer/flush lists。 1 MySQL redo_log简要回顾 在MySQL 5.7中写性能
腾讯数据库技术
2019/05/16
1.9K0
MySQL-8.0 redo优化剖析
图文结合带你搞懂MySQL日志之Redo Log(重做日志)
请读者注意:本文基于 GreatSQL 8.0.25 & MySQL 5.7.7-RC版本,在 MySQL8.0.30 Redo 发生变化,详情见: MySQL 8.0.30动态redo log初探
老叶茶馆
2023/02/18
8680
图文结合带你搞懂MySQL日志之Redo Log(重做日志)
redo log-Transaction(2)—mysql进阶(六十)
前面我们说了为了吧buffer pool的数据持久化到磁盘上,比如修改了一条数据,不可能每次吧整个页的数据都刷新过去,这样耗费性能,innoDB就是把修改的数据记录在redo日志里,redo日志格式主要是spaceId,type,page_number,offset,Data等。Offset记录上一条数据的地址,为了修改上一条记录头部新的next record,data记录的就是真实数据。Redo日志主要关注的就是一条语句修改了多少b+树,针对其中某颗树,可能增加了页,也可能更新了叶子节点或者内节点。他会记录修改日志或者删除日志,而删除日志格式又会分为开始和结束,MLOG_COMP_LIST_START_DELETE和MLOG_COMP_LIST_END_DELETE。
用户9919783
2022/07/29
2850
详细分析 MySQL 事务日志(redo log 和 undo log)
InnoDB 事务日志包括redo log和undo log,其中redo log是重做日志,提供前滚操作;undo log是回滚日志,提供回滚操作。undo log不是redo log的逆向过程,其实它们都算是用来恢复的日志:
CG国斌
2020/05/26
1.9K0
MySQL持久化不为人知的一面⭐️卡顿现象的根源与对策
2024新年新气象,小菜同学又踏上了求职之路,但求职路艰辛,新年第一次面试又被面试官给问住了
菜菜的后端私房菜
2024/06/25
4441
MySQL 8.0源码学习日记——redo log的一生
最开始了解mysql实现的时候,总听到redo log, WAL(write-ahead logging),undo log这些关键词,了解到redo log主要是用于实现事务的持久化的。为了进一步了解redo log,看了下相关代码(源码版本: mysql 8.0.12),这里简单总结下,主要介绍redo log是如何产生,如何落盘,以及最终通知用户的。
brightdeng@DBA
2021/03/11
9310
MySQL 8.0源码学习日记——redo log的一生
详解MySQL的Redo日志与Undo日志
本文分两部分, 第一部分概念介绍,重在理解。 第二部分通过MySQL Innodb中的具体实现,加深相关知识的印象。 本文的原意是一篇个人学习笔记,为了避免成为草草记录一下的流水账,尝试从给人介绍的角度开写。但在整理的过程中,越来越感觉力不从心,一是细节太多了,原以为足够了解的一个小知识点下可能隐藏了很多细节;二是内容与范围的取舍,既想有点技术性避免空谈,又不想陷入枯燥冗长的小细节描述。几番折腾,目前的想法把坑填上,能写完就不错了,你读起来有不顺或错误的地方请见谅,欢迎反馈。
Bug开发工程师
2020/02/12
2.4K0
详解MySQL的Redo日志与Undo日志
相关推荐
Redo日志 (4)—log sequence number(六十二)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档