当前位置: 首页 > news >正文

重做日志-redo log

1、设计思路

  可以先说:为什么要引入内存(buffer pool)?

  mysql中的数据是存储在硬盘中的,读、写数据都需与磁盘进行交互。如读取数据,首先从磁盘中获取到数据,然后放到内存中,待到下次同样的查询直接从内存中获取;再如,更新数据依然是先从磁盘获取数据存放到内存,然后对内存中的数据更改完毕后,再进行刷盘的操作,以此完成写操作。

  对于少量数据,数据库可以接受,但是对于大量数据以及访问量,数据库一时的磁盘IO次数将会大大增加,势必给其带来不少的压力,以至于数据库会崩溃。

  为了解决这一问题,我们可以从刷盘处入手,当数据需要更新时,先使用一个文件对更新操作进行记录,然后再更新内存,在适当的时候对数据进行统一的刷盘操作,而这个文件就是redo log,该技术也被称为WAL技术,WAL的全称是Write-Ahead Logging,即先写日志,再写磁盘。该技术主要就是为了减少sql执行期间的数据库io操作次数,并且更新磁盘往往是在Mysql比较闲的时候,这样就大大减轻了Mysql的压力。

  此外,当内存中的脏页进行刷盘,而MySQL宕机时,如果没有redo log的话,修改后的数据就会丢失。

2、redo log介绍

  首先,提出一个问题:redo log是否对其文件大小有限制?若有限制,当超过其限制时,数据库会做出怎样对应的操作?

  解一:redo log文件的大小

InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是 1GB,那么这个日志总共就可以记录4GB的操作。并且写redo log是环状写日志的形式,如下图。

  • write pos是当前记录的位置,一边写一边后移。
  • check point是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

规定:write pos和checkpoint之间的是日志上还空着的部分,可以用来记录新的操作。如果write pos 追上checkpoint,表示日志满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint推进一下。

总结:有了redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe。

3、产生的 redo log 是直接写入磁盘的吗?

  实际上,执行一个事务的过程中,产生的 redo log 也不是直接写入磁盘的,因为这样会产生大量的 I/O 操作,而且磁盘的运行速度远慢于内存。

  所以,redo log 也有自己的缓存—— redo log buffer,每当产生一条 redo log 时,会先写入到 redo log buffer,后续在持久化到磁盘如下图:

  redo log buffer 默认大小 16 MB,可以通过 innodb_log_Buffer_size 参数动态的调整大小,增大它的大小可以让 MySQL 处理「大事务」是不必写入磁盘,进而提升写 IO 性能。

4、redo log 的刷盘时机?

  缓存在 redo log buffer 里的 redo log 还是在内存中,它主要有下面几个刷盘时机:

  • MySQL 正常关闭时;
  • 当 redo log buffer 中记录的写入量大于 redo log buffer 内存空间的一半时,会触发落盘;
  • InnoDB 的后台线程每隔 1 秒,将 redo log buffer 持久化到磁盘。
  • 每次事务提交时都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘
http://www.dtcms.com/a/301436.html

相关文章:

  • 决策树(Decision Tree)完整解析:原理 + 数学推导 + 剪枝 + 实战
  • 无向图的连通性问题
  • Qt C++ GUI 函数参数速查手册:基础与布局
  • Android 调试桥 (adb) 基础知识点
  • 通过knn算法实现识别数字
  • 【n8n教程笔记——工作流Workflow】文本课程(第一阶段)——5.4 计算预订订单数量和总金额 (Calculating booked orders)
  • nacos连接失败,启动失败常见问题
  • OpenCV-图像预处理③【图像梯度计算、边缘检测算法(如 Canny)、轮廓提取与分析、凸包特征检测,以及 轮廓的外接几何特征(如最小外接矩形、外接圆等)】
  • 硅基计划3.0 学习总结 肆 二叉树 初版
  • [每周一更]-(第148期):使用 Go 进行网页抓取:Colly 与 Goquery 的对比与思路
  • QT---概览
  • 优化Linux高并发:文件描述符与端口范围的协同调优
  • SPSC无锁环形队列技术(C++)
  • FreeRTOS—空闲任务
  • 【Python系列】Flask 应用中的主动垃圾回收
  • idea打开后project窗口未显示项目名称的解决方案
  • LangGraph快速入门项目部署
  • C++ 中实现 `Task::WhenAll` 和 `Task::WhenAny` 的两种方案
  • 从0搭建YOLO目标检测系统:实战项目+完整流程+界面开发(附源码)
  • jenkins只能运行2个任务,提示:“等待下一个可用的执行器”
  • Redis C++客户端——命令使用
  • 实战演练1:实战演练之命名实体识别
  • Docker 的数据持久化-数据卷
  • (AC)架子鼓
  • 基于Java的KTV点歌系统的设计与实现
  • 【CF】Day112——杂题 (逆向思维 | 二分 + 贪心 | 单调队列优化DP | 二进制 + 前缀和 | 二分图判断 | 暴力枚举)
  • JavaEE--3.多线程
  • python-装饰器
  • 【ST表、倍增】P7167 [eJOI 2020] Fountain (Day1)
  • QT6 源,七章对话框与多窗体(15)多文档 MDI 窗体 QMdiArea 篇一:属性,公共成员函数,信号与槽函数