图解MySQL【日志】——Redo Log

news/2025/2/22 23:27:30

Redo Log(重做日志)

为什么需要 Redo Log?

1. 崩溃恢复

  • 数据库崩溃时,系统通过 Redo Log 来恢复尚未写入磁盘的数据。Redo Log 记录了所有已提交事务的操作,系统在重启后会重做这些操作,以保证数据不会丢失。

2. 提高性能

  • 使用 Redo Log 可以避免每次修改都立即写入磁盘(随机写),而是先将修改操作写入 Redo Log(顺序写),然后将数据写入内存,最后再异步地将数据写入磁盘,减少了磁盘 I/O 的次数,提高了性能。

3. 事务一致性

  • 即使数据库在执行过程中崩溃,Redo Log 也可以帮助恢复所有已提交的事务,确保数据库恢复到一致(Consistency)的状态。

Redo Log 是什么?

  • Redo Log 是物理日志,记录了某个数据页做了什么修改,如对 AAA 表空间中的 BBB 数据页 CCC 偏移量的地方做了 DDD 更新,每当执行一个事务,就会产生一条或多条物理日志。
  • 在事务提交时,只要保证 Redo Log 被持久化到磁盘即可,可以不需要等到将缓存在 Buffer Pool 里的脏页数据持久化到磁盘。即使系统崩溃,Redo Log 已完成持久化,等待 MySQL 重启后,可以根据 Redo Log 的内容,将所有数据恢复到最新状态。

WAL(Write-Ahead Logging)技术

核心思想

  • 先写日志:修改数据之前,先将修改操作记录到日志文件中,之后择机再写到磁盘中。
  • 崩溃恢复:这样即使崩溃,数据也能通过日志恢复到一致的状态。
  • 顺序写 VS 随机写:Redo Log 采用顺序循环写的方式,写入磁盘的速度远大于直接写入磁盘的顺序写方式。

过程如图


Redo Log 的持久化过程

1. Redo Log Buffer

  • 在事务执行过程中,产生的 Redo Log 也不是直接刷盘的,而是先写入 Redo Log Buffer,后续再择机刷入磁盘中。
  • 默认大小为 16MB,可通过 innodb_log_Buffer_size 参数动态调整大小,增大时,可以让 MySQL 处理【长事务】时不必写入磁盘,提升写 I/O 性能。

2. Redo Log 什么时候刷盘?

缓存在 Redo Log Buffer 中的 Redo Log 还是在内存中,刷盘时机如下:

  • MySQL 正常关闭时。
  • Redo Log Buffer 中记录的写入量大于总内存空间(由 innodb_log_Buffer_size 控制)的一半时,触发落盘。
    • 超过一半就落盘的原因:在性能数据安全之间找到一个平衡点。
  • InnoDB 的后台线程每隔 1s,将 Redo Log Buffer 持久化到磁盘。
  • 每次提交事务时,将 Redo Log Buffer 持久化到磁盘,由 innodb_flush_log_at_trx_commit 参数控制。

3. innodb_flush_log_at_trx_commit 参数

决定 Redo Log 的刷盘时机。

0 :每次事务提交,将 Redo Log 留在 Redo Log Buffer 中,该模式下,事务提交时不会主动触发落盘操作。
  • 写入磁盘时机:等待 InnoDB 后台线程每隔 1s,先写入 OS 的 Page Cache,后调用 fsync() 持久化到磁盘。
  • 数据安全性:MySQL 崩溃时,会导致上 1s 所有事务数据丢失

1(默认):每次事务提交,将缓存在 Redo Log Buffer 中的 Redo Log 直接持久化到磁盘中。
  • 安全性:该模式可以保证 MySQL 异常重启后,数据不会丢失。

2:每次事务提交时,都只将缓存在 Redo Log Buffer 中的 Redo Log 写到 Redo Log 文件(OS 的 Page Cache,系统文件缓存),而非磁盘。
  • 写入磁盘时机:等待 InnoDB 后台线程每隔 1s,调用 fsync() 将 Page Cache 中的 Redo Log 持久化到磁盘。
  • 数据安全性:MySQL 崩溃时不会导致数据丢失,只有在 OS 崩溃或系统断电的情况下,丢失上 1s 所有事物数据

数据安全性对比:参数 1 > 参数 2 > 参数 0

写入性能对比:参数 1 < 参数 2 < 参数 0

每种参数对应的写入过程

4. Redo Log 怎样写入?

重做日志文件组(Redo Log Group):
  • 默认情况下,InnoDB 存储引擎有一个 Redo Log Group,该重做日志文件组由 2 个 Redo Log 文件组成,且每个 Redo Log File 的大小固定且一致,如下图


循环写:
  • Redo Log Group 是以循环写方式工作的,即从头开始写,写到末尾再循环到开头,相当于环形。

  • 具体过程:Redo Log 是避免防止 Buffer Pool 中的脏页丢失而设计的,但随着系统运行,Buffer Pool 中的脏页逐步被刷新到磁盘中,Redo Log 也需要更新自己的空间,擦除已刷新到磁盘中的旧记录,为新的脏页数据腾出空间。

    • write pos:Redo Log 当前记录写到的位置。
    • check point:表示当前要擦除的位置。
    • write pos~check point(红色部分):用来记录新的更新操作。
      • write pos 追上 check point 时表示 Redo Log 文件已满,这时 MySQL 不能执行新的更新操作,即被阻塞(故大并发量的系统,将 Redo Log 文件大小设置为适当的值很有必要),此时会停下来将 Buffer Pool 中的脏页数据刷新到磁盘中,然后标记 Redo Log 哪些记录可以被擦除,接着对旧 Redo Log 记录进行擦除,等擦除完成并腾出空间后,check point就会往后移动,MySQL 恢复正常,继续执行新的更新操作。
    • check point~write pos(蓝色部分):待落盘的脏数据页记录。
      • 一次 check point 的过程就是脏页数据刷新到磁盘中变成干净页,然后标记 Redo Log 记录中哪些记录可以被覆盖的过程。


http://www.niftyadmin.cn/n/5862842.html

相关文章

JUC并发—9.并发安全集合四

大纲 1.并发安全的数组列表CopyOnWriteArrayList 2.并发安全的链表队列ConcurrentLinkedQueue 3.并发编程中的阻塞队列概述 4.JUC的各种阻塞队列介绍 5.LinkedBlockingQueue的具体实现原理 6.基于两个队列实现的集群同步机制 4.JUC的各种阻塞队列介绍 (1)基于数组的阻塞…

Springboot 高频面试题

以下是Spring Boot的高频面试题及答案和底层原理解释&#xff1a; 基础概念 什么是Spring Boot&#xff0c;其主要特点是什么&#xff1f; 答案&#xff1a; Spring Boot本质上是一个建立在Spring框架之上的快速应用开发框架。其主要特点包括&#xff1a; 启动器&#xff1a;一…

力扣LeetCode: 2209 用地毯覆盖后的最少白色砖块

题目&#xff1a; 给你一个下标从 0 开始的 二进制 字符串 floor &#xff0c;它表示地板上砖块的颜色。 floor[i] 0 表示地板上第 i 块砖块的颜色是 黑色 。floor[i] 1 表示地板上第 i 块砖块的颜色是 白色 。 同时给你 numCarpets 和 carpetLen 。你有 numCarpets 条 黑…

go 错误处理 error

普通错误处理 // 包路径 package mainimport ("errors""fmt" )func sqrt(f1, f2 float64) (float64, error) {if f2 < 0 {return 0, errors.New("error: f2 < 0")}return f1 / f2, nil }func sqrt1(f1, f2 float64) {if re, err : sqrt(f…

Python中的Flask深入认知搭建前端页面?

一、Flask 的介绍 1. 什么是Flask&#xff1f; Flask 是一个轻量级的 Python Web 框架&#xff0c;因其简单易用、灵活性高而广受欢迎。它适合快速开发小型应用&#xff0c;也可以通过扩展支持复杂的功能需求。可以结合 HTML、CSS 和 JavaScript 实现丰富的交互功能。 2. 核…

【C# 数据结构】队列 FIFO

目录 队列的概念FIFO (First-In, First-Out)Queue<T> 的工作原理&#xff1a;示例&#xff1a;解释&#xff1a; 小结&#xff1a; 环形队列1. **FIFO&#xff1f;**2. **环形缓冲队列如何实现FIFO&#xff1f;**关键概念&#xff1a; 3. **环形缓冲队列的工作过程**假设…

YOLOv11-ultralytics-8.3.67部分代码阅读笔记-split_dota.py

split_dota.py ultralytics\data\split_dota.py 目录 split_dota.py 1.所需的库和模块 2.def bbox_iof(polygon1, bbox2, eps1e-6): 3.def load_yolo_dota(data_root, split"train"): 4.def get_windows(im_size, crop_sizes(1024,), gaps(200,), im_rate_t…

中文Build a Large Language Model (From Scratch) 免费获取全文

中文pdf下载地址&#xff1a;https://pan.baidu.com/s/1aq2aBcWt9vYagT2-HuxdWA?pwdlshj 提取码&#xff1a;lshj 原文、代码、视频项目地址&#xff1a;https://github.com/rasbt/LLMs-from-scratch 翻译工具&#xff1a;沉浸式翻译&#xff08;https://app.immersivetrans…