【每日八股】MySQL篇(七):日志(上)

devtools/2025/3/4 18:23:07/

目录

  • MySQL 三种日志?
    • 二进制日志(Binlog)
    • 重做日志(Redo Log)
    • 回滚日志(Undo Log)
    • 其它辅助日志
    • 总结
  • redo log 与 undo log 的区别?
  • undo log 是如何实现 MVCC 的?
  • redo log 与 binlog 的区别?
  • 为什么有 binlog,还需要有 redo log?
    • 什么是 crash-safe?
    • 什么是 WAL 技术?
  • 被修改的 undo 页面,需要记录对应的 redo log 吗?
  • binlog 的三种格式?
  • redo log 容灾恢复过程?
  • redo log 是直接写入磁盘的吗?
  • redo log 先写入 buffer 再落盘与直接落盘相比,有什么优点?
  • redo log buffer 什么时候刷盘?
  • redo log 文件格式和写入过程?
    • 文件格式
      • 物理结构
      • 逻辑结构
      • LSN(Log Sequence Number)
    • 写入过程
      • 事务提交阶段
      • 日志写入流程
      • Checkpoint 机制
    • 崩溃恢复
    • 关键设计思想

MySQL 三种日志?

【在 csview 上这条八股题目被命名为 “MySQL 三种日志?”,但 DeepSeek 给出的答案我个人认为更加完整,csview 中总结的 undo log、redo log 和 bin log 应该被称为 MySQL 的三个核心日志,此外还有error log、slow query log 和 general query log 等辅助日志】

首先总结三种核心日志。

二进制日志(Binlog)

作用:记录所有修改数据库的 SQL 语句(逻辑日志),用于主从复制和数据恢复。

特点:属于 MySQL Server 层的日志,与存储引擎无关。

重做日志(Redo Log)

作用:确保事务的持久性,主要用于掉电等故障恢复。记录物理页的修改,用于崩溃恢复时重放未持久化到磁盘的操作。

特点:属于 InnoDB 引擎层日志,采用循环写入模式。

回滚日志(Undo Log)

作用:提供事务回滚能力(原子性)。支持 MVCC(多版本并发控制),实现非锁定读。

特点:属于 InnoDB 引擎层日志,记录事务前的数据旧版本。事务提交后不会立即删除,可能被其他事务的 MVCC 读取依赖。

其它辅助日志

  • 错误日志(Error Log):记录 MySQL 启动、运行、停止时的错误信息;
  • 慢查询日志(Slow Query Log):记录执行时间超过阈值的 SQL,用于性能优化;
  • 通用查询日志(General Query Log):记录所有客户端请求(生产环境慎用);

总结

Binlog 用于数据恢复与数据复制;Redo Log 保障崩溃恢复(比如掉电恢复);Undo Log 用于事务回滚与 MVCC。

redo log 与 undo log 的区别?

redo log 记录的是此次事务完成后的数据状态,undo log 记录的是此次事务开始前的数据状态。

undo log 是如何实现 MVCC 的?

对于读提交和可重复读隔离级别,快照读是通过 Read View + undo log 来实现的。这两种隔离级别下快照读的主要区别是建立 Read View 的时机不同:

  • 读提交(Read Committed)在每个 select 语句执行时都会生成一个新的 Read View,事务执行期间如果多次读取同一条数据,则前后两次读的数据可能会出现不一致(原因在于,在读提交隔离级别下,一个事务提交之后,其所做的更改会被其它事务看到,即不能保证可重复读),因为在此期间可能另一个事务修改了这条记录,并提交了事务。
  • 可重复读隔离级别是在启动事务时生成一个 Read View,然后整个事务期间,所有的 select 语句共用一个 Read View,保证事务期间读到的数据都是事务启动前的记录。

通过对比事务的 Read View 当中字段和记录的隐藏列 trix_id 和 roll_pointer,如果不满足版本可见行,就会顺着 undo log 版本链找到满足可见性的记录,从而控制并发事务访问同一个记录时的行为。

redo log 与 binlog 的区别?

  • 架构分层差异:binlog 在 MySQL 的 Server 层实现,所有存储引擎都可以用;而 redo log 是 InnoDB 存储引擎实现的日志;
  • 文件格式不同:binlog 是逻辑日志,记录原始 SQL 语句或行变更逻辑;redo log 是物理日志,记录的是在某个数据页做了什么样的修改。物理日志恢复效率更高(直接应用物理修改),逻辑日志更通用但是恢复速度慢;
  • 写入方式不同:binlog 是追加写,写满一个文件,就会创建一个新的文件继续写,不会覆盖以前的日志,保存的是全量的日志;redo log 是循环写,日志空间大小固定,全部写满就从头开始,保存未被刷入磁盘的脏页日志。循环写入更适合高频事务场景,避免日志文件无限膨胀;
  • 用途不同:binlog 用于数据备份和数据恢复;redo log 用于故障恢复;

为什么有 binlog,还需要有 redo log?

早期版本的 MySQL 以 MyISAM 作为默认的数据引擎,它没有 crash-safe 的能力,binlog 日志仅用于归档。InnoDB 数据引擎可以通过 redo-log 实现 crash-safe 能力。

什么是 crash-safe?

基于 redo log 和 WAL 技术,InnoDB 可以保证即使数据库异常重启,之前已经提交的数据也不会丢失。

什么是 WAL 技术?

WAL 指的是,MySQL 的写操作不是立刻写到磁盘上,而是先写日志,然后在合适的时间写到磁盘。

被修改的 undo 页面,需要记录对应的 redo log 吗?

需要。开启事务后,InnoDB 更新记录前,首先要记录相应的 undo log,如果是更新操作,也就是要生成一条 undo log,undo log 会写入 Buffer Pool 中的 Undo 页面。在内存修改该 Undo 页面后,需要记录对应的 redo log。

binlog 的三种格式?

分别是 STATEMENT(默认格式)、ROW、MIXED;

  • STATEMENT:每一条修改数据的 SQL 都会被记录到 binlog 中,主从复制从 slave 端根据 SQL 语句重现;
  • ROW:记录行数据最终被修改成什么样了,不会出现 STATEMENT 动态函数问题;
  • MIXED:包含了 STATEMENT 和 ROW 模式,它会根据不同的情况自动使用 ROW 模式和 STATEMENT 模式;

redo log 容灾恢复过程?

如果 redo log 是完整的(commit 状态),那么直接使用 redo log 恢复;

如果 redo log 是预提交 prepare 而不是 commit 状态,此时要去判断 binlog 是否完整,完整就提交 redo log,再用 redo log 恢复,不完整就回滚事务。

redo log 是直接写入磁盘的吗?

不是。直接写入磁盘会产生大量 I/O,redo log 会先写入 redo log buffer,每当产生一条 redo log,先写入 buffer,后续再持久化到磁盘。

以上是 csview 整理的答案,而根据 DeepSeek 给出的回答,实际上 redo log 是否直接落盘取决于 MySQL 的配置策略,由参数innodb_flush_log_at_trx_commit控制。

  • innodb_flush_log_at_trx_commit = 1 时,每次事务提交,log buffer 中的 redo log 都会立即直接写入操作系统缓存并调用fsync刷盘,确保事务提交后数据不丢失,但会降低吞吐量;
  • innodb_flush_log_at_trx_commit = 0 时,log buffer 每秒写入 OS 缓存并刷盘一次,事务提交时不主动触发写盘。风险是最多都是 1 秒的事务数据;
  • innodb_flush_log_at_trx_commit = 2 时,事务提交时 log buffer 写入 OS 缓存,但每秒调用 fsync 落盘一次。风险是 OS 崩溃时丢失 1 秒数据,硬件故障也可能丢失。

redo log 先写入 buffer 再落盘与直接落盘相比,有什么优点?

redo log 的写方式使用了追加,日志操作是顺序写,磁盘操作是随机写,MySQL 的写操作从磁盘的随机写变成了顺序写,提升语句的执行性能。

  • 实现事务的持久性,让 MySQL 有 crash-safe 的能力,能够保证 MySQL 在任何时间段突然崩溃,重启后之前已提交的记录都不会丢失;
  • 将写操作从随机写变成了顺序写,提升 MySQL 写入磁盘的性能。

redo log buffer 什么时候刷盘?

  • MySQL 正常关闭时触发落盘;
  • 当 redo log buffer 中记录的数据大于 redo log buffer 内存空间的一半时,触发落盘;
  • InnoDB 的后台线程每隔 1 秒,将 redo log buffer 持久化到磁盘;
  • 每次事务提交时都将缓存在 redo log buffer 里的 redo log 持久化到磁盘。

redo log 文件格式和写入过程?

文件格式

物理结构

ib_logfile0ib_logfile1 等文件组成(默认2个,可配置)。每个文件大小固定(如48MB),以循环写入(Circular Buffer)方式复用。

逻辑结构

日志块(Log Block):每个块512字节(与磁盘扇区对齐);

日志记录(Log Record):每个事务的修改操作记录。包含表空间ID、页号、修改内容等元数据。

LSN(Log Sequence Number)

全局递增的唯一序列号,标记日志写入位置,用于崩溃恢复时定位数据一致性点。

写入过程

事务提交阶段

修改操作先写入内存中的 redo log buffer,根据 innodb_flush_log_at_trx_commit (0 / 1 / 2)配置决定刷盘策略。

日志写入流程

将 redo log buffer 中的日志按 LSN 顺序写入文件。写入时追加到当前活跃的日志文件(如ib_logfile0)。若文件写满,切换到下一个文件(循环覆盖旧日志)

Checkpoint 机制

  • 定期将脏页(修改后的数据页)刷入磁盘;
  • 更新Checkpoint LSN,标记已持久化的日志位置;
  • 释放已无用的日志空间(避免无限增长);

崩溃恢复

  1. 重启时比较 Checkpoint LSN 和最新 LSN;
  2. 重放 Checkpoint 之后的所有日志记录;
  3. 确保未刷盘的脏页修改被恢复;

关键设计思想

  1. 顺序写入:日志追加写性能远高于随机写数据文件;
  2. WAL:先写日志后写数据;
  3. 幂等性:日志记录包含足够信息,可重复执行恢复。

http://www.ppmy.cn/devtools/164530.html

相关文章

Python 创建一个能够筛选文件的PDF合并工具

合并多个 PDF 文件。这款 PDF 合并工具允许用户浏览文件夹、选择 PDF 文件,并将其合并为一个新的 PDF 文件。我们将详细分析代码结构和如何一步步实现每个功能。 C:\pythoncode\new\PDFFileInFolderMergeToNewPDFFile.py 全部代码 import os import wx import PyP…

互联网时代如何保证数字足迹的安全,以防个人信息泄露?

用户在网络上所做的几乎所有事情,包括浏览、社交媒体活动、搜索查询、在线订阅,甚至购物,都会留下一条数据线索,这些数据可用于创建用户在线身份的详细档案。如果这些信息暴露,恶意行为者可能会利用它们将用户置于各种…

Grafana接入Zabbix数据源

1. 对接 Zabbix 1.1 安装 Zabbix 插件 在线安装&#xff1a; 1.2 配置 Zabbix 数据源 点击 Configuration > Data Sources > Add data source。选择 Zabbix&#xff0c;填写&#xff1a; URL&#xff1a;http://<zabbix-server>/api_jsonrpc.phpUsername&#x…

C# dll文件的反编译获取源码

目录 前言操作流程结论 前言 上一篇文章介绍了将C# cs类文件加密为dll文件&#xff0c;在此给大家写一篇关于反编译dll文件的文章。 操作流程 首先&#xff0c;我们需要准备一个C#反编译工具&#xff0c;我这里用的是免费的软件JetBrains dotPeek&#xff0c;类似的有很多&am…

Windows 环境下 Nginx、PHP 与 ThinkPHP 开发环境搭建

Windows 环境下 Nginx、PHP 与 ThinkPHP 开发环境搭建 目录 安装 Nginx 和 PHP配置 Nginx配置 PHP启动服务ThinkPHP 配置常见问题排查 1. 安装 Nginx 和 PHP 安装 Nginx 访问 Nginx 官网 下载 Windows 版本解压到指定目录&#xff0c;如 C:\nginx 安装 PHP 访问 PHP 官网…

C# 矩形面积和周长的程序(Program for Area And Perimeter Of Rectangle)

矩形是平面上的平面图形。 它有四条边和四个相等的角&#xff0c;每个角都是 90 度。 矩形的四条边并不像正方形那样长度相等&#xff0c;而是彼此相对的边长度相等。 矩形的两条对角线长度相等。 例子&#xff1a; 输入&#xff1a;4 5 输出&#xff1a;面积 20 …

HttpServletRequest 和 HttpServletResponse 不同JDK版本的引入

java中&#xff0c;可能会用到JWT令牌校验&#xff0c; 这时&#xff0c;大概率会用到 HttpServletRequest&#xff0c;和 HttpServletResponse。 若为 JDK8&#xff0c;SpringBoot 2.7.3 的版本则引入&#xff1a; import javax.servlet.http.HttpServletRequest; import ja…

【多线程-第三天-NSOperation的练习-tableView异步下载网络图片-沙盒缓存 Objective-C语言】

一、沙盒缓存 1.下边我们来看沙盒缓存,但是,我们先要来看一下,为什么要学这个东西,为什么要做这件事情,好,我们先来运行一下我们的程序, 好,图片,先是从网络上下载, 下载完成之后,就保存到了内存中,保存到我们那个图片的缓存池中来,现在,我把程序关掉,我再开,图…