mysql--核心日志文件详解

引言:

mysql中日志文件是非常重要,mysql的各种特性和功能都是基于日志文件实现的,本文将详细介绍mysql的日志文件

一、日志类型(仅介绍重要的)

1.Undo Log

(1)作用

  • 实现事务的原子性(Atomicity)
  • 用于事务回滚(ROLLBACK),当事务执行失败或显式回滚时,可以通过 Undo Log 恢复到事务开始前的状态。
  • 支持多版本并发控制(MVCC),实现非锁定读(如 SELECT 不加锁也能读到历史版本)。

(2)存储位置

  • 存储在 InnoDB 存储引擎的表空间中(可以是系统表空间或独立的 Undo 表空间)。
  • 从 MySQL 5.6 开始支持独立的 Undo 表空间(通过 innodb_undo_tablespaces 配置)。

(3)工作机制

  • 当一条记录被修改时,InnoDB 会先将修改前的旧值(旧版本)写入 Undo Log。
  • 每个事务有自己的 Undo Log 记录,形成一个链表(Undo Log Chain)。
  • 当事务提交后,Undo Log 并不会立即删除,而是标记为"可清理"状态,供 MVCC 使用。
  • 后台线程(Purge Thread)在确认没有事务需要这些旧版本后,才会真正删除 Undo 日志

(4)示例

sql 复制代码
BEGIN;
UPDATE users SET age = 25 WHERE id = 1;
-- 此时,原 age 值(比如20)被写入 Undo Log
ROLLBACK;
-- 使用 Undo Log 回滚,age 恢复为 20

2. Redo Log

1. 作用

  • 保证事务的持久性(Durability)
  • 确保即使在数据库崩溃后,已提交的事务修改也不会丢失。
  • 通过 WAL(Write-Ahead Logging,预写日志)机制,先写日志再写数据页。

2. 存储位置

  • 物理文件,位于 MySQL 数据目录下,通常为 ib_logfile0ib_logfile1
  • 文件大小固定(由 innodb_log_file_size 控制),循环写入。

3. 工作机制

  • 事务执行过程中,对数据页的修改会先记录到 Redo Log Buffer(内存中)。
  • 当满足一定条件(如事务提交、Buffer满、每秒刷新等),Redo Log Buffer 会被刷新到磁盘的 Redo Log 文件中。
  • 数据页的真正修改可以异步写入磁盘(由后台线程完成),提高性能。
  • 数据库崩溃恢复时,通过 Redo Log 重放(replay)已提交但未落盘的事务操作,恢复数据。

4. 关键参数

  • innodb_log_file_size:单个日志文件大小(建议设置为 1~2GB)。
  • innodb_log_files_in_group:日志文件数量(默认2)。
  • innodb_flush_log_at_trx_commit:控制日志刷盘策略:
    • 1:每次事务提交都刷盘(最安全,性能略低)。
    • 0:每秒刷一次,事务提交不刷盘(性能高,可能丢失1秒数据)。
    • 2:事务提交写入 OS 缓存,每秒刷盘(折中方案)。

5. 示例

sql 复制代码
BEGIN;
UPDATE users SET age = 30 WHERE id = 1;
COMMIT;
-- 提交时,Redo Log 写入磁盘,即使此时数据页未写入磁盘,崩溃后也能恢复

sql

BEGIN; UPDATE users SET age = 30 WHERE id = 1; COMMIT; -- 提交时,Redo Log 写入磁盘,即使此时数据页未写入磁盘,崩溃后也能恢复

3.Binlog(二进制文件)

(1)作用

  • 记录所有修改数据的 SQL 语句或行变更(取决于格式)。
  • 用于数据库的主从复制(Replication)数据恢复(Point-in-Time Recovery)
  • 由 MySQL Server 层维护,与存储引擎无关(所有引擎都能记录 Binlog)。

(2)存储位置

  • 文件形式,位于 MySQL 数据目录下,如 mysql-bin.000001mysql-bin.000002 等。
  • 可以配置自动删除过期日志(通过 expire_logs_daysbinlog_expire_logs_seconds)。

(3)日志格式(三种模式)

全屏复制

格式 说明 优缺点
STATEMENT 记录 SQL 语句本身 日志量小,但可能在从库产生不一致(如使用 NOW() 函数)
ROW 记录每一行数据的变更(推荐) 安全、精确,适合复制,但日志量大
MIXED 混合模式,MySQL 自动选择 一般默认使用,兼顾安全与性能

(4)写入时机

  • 事务提交时,由 MySQL Server 层将变更写入 Binlog(在存储引擎提交之前或之后,取决于参数)。
  • 通过 sync_binlog 控制刷盘频率:
    • 0:由操作系统决定(性能高,风险高)。
    • 1:每次事务提交都刷盘(最安全,性能稍低)。
    • N:每 N 个事务提交刷一次。

(5)使用场景

  • 主从复制:主库 Binlog 发送给从库,从库通过 SQL Thread 回放日志。
  • 数据恢复 :通过 mysqlbinlog 工具解析 Binlog,恢复到某个时间点。

4.Doublewrite Buffer(双写缓冲)

✅ 是否属于"日志"?

严格来说不是日志文件,但它是 一种保障数据页写入一致性的机制,常与 Redo Log 配合使用,防止"部分写问题"(partial page write)。

🔍 作用

  • 防止在数据库崩溃时出现"页断裂"(Page Corruption)。
  • 当 InnoDB 将脏页刷新到磁盘时,如果写入过程中断电,可能导致页面只写了一半(512字节 out of 16KB),造成数据损坏。
  • Doublewrite Buffer 先将页面写入一个连续的、安全的区域(系统表空间中的双写缓冲区),再写入实际的数据文件位置。

📍 工作流程:

  1. 脏页从 Buffer Pool 刷出时,先批量写入 Doublewrite Buffer 区域(物理上连续)。
  2. 再将这些页写入各自在 .ibd 文件中的目标位置。
  3. 崩溃恢复时,如果发现某页校验失败,可以从 Doublewrite Buffer 中恢复完整的副本。

5.Change Buffer(变更缓冲)

✅ 是否属于"日志"?

不是传统日志,但它记录的是对二级索引页的延迟修改操作,具有"延迟写 + 缓冲"的特性,类似轻量级日志。

🔍 作用

  • 提高 DML 操作(INSERT/UPDATE/DELETE)性能,尤其是在大量随机写入场景下。
  • 对于非唯一二级索引的更新,如果不影响主键索引,InnoDB 会将修改暂存到 Change Buffer,而不是立即读取并修改对应的索引页(避免随机 I/O)。
  • 后续当该页被加载到内存时,再进行合并(merge)。

🔄 合并时机:

  • 查询访问该页时。
  • 后台线程定期合并。
  • 系统空闲或刷新脏页时。

6.Error Log(错误日志)

属于 MySQL Server 层,但 InnoDB 的严重错误也会写入其中

🔍 作用

  • 记录 InnoDB 初始化、崩溃、恢复、死锁、表空间异常等关键事件。
  • 是排查 InnoDB 故障的重要依据。

7. InnoDB Recovery Logs(恢复日志信息)

这不是独立文件,而是指 InnoDB 在启动时通过 Redo Log 自动执行恢复过程的日志输出,通常打印在 Error Log 中。

8.Slow Query Log(慢查询日志)

用来分析 InnoDB 表的锁等待、长事务、全表扫描等问题。

二、sql语句执行过程中日志写入顺序和触发时机

示例 SQL

sql 复制代码
BEGIN;
UPDATE users SET age = 30 WHERE id = 1;
COMMIT;

1.整体流程概览

阶段 操作 写入日志
1. 开始事务 BEGIN 无日志写入
2. 执行 UPDATE 修改数据页 写 Undo Log + Redo Log(内存)
3. 提交事务 COMMIT Redo Log 刷盘 → 写 Binlog → Binlog 刷盘 → InnoDB 提交

2.详细时间线:

时间点 操作 写入内容 写入位置 是否刷盘(持久化)
T0 BEGIN; -
T1 UPDATE ... 旧值写入 Undo Log Undo Log Buffer(内存)
T1 UPDATE ... 修改数据页 Buffer Pool(内存)
T1 UPDATE ... 生成 Redo Log 记录 Redo Log Buffer(内存)
T2 (Prepare) COMMIT 开始 事务状态 → PREPARED Redo Log Buffer ✅ (fsync)
T2 (Prepare) COMMIT 开始 所有 Redo Log 刷盘 ib_logfile*
T2 (Commit) 写 Binlog 更新事件写入 Binlog Binlog Cache → .binlog ✅ (fsync, sync_binlog=1)
T2 (Commit) 最终提交 事务状态 → COMMITTED InnoDB 内部结构 ✅(通过 Redo Log)

3.💥 崩溃恢复场景分析

假设在不同阶段发生崩溃,MySQL 如何恢复?

崩溃时间点 恢复行为
UPDATE 后,未 COMMIT 重启后回滚该事务(通过 Undo Log)
Prepare 阶段后,未写 Binlog 重启后发现 PREPARED 事务,但无对应 Binlog → 回滚
Binlog 写完后,未最终提交 重启后发现 PREPARED 事务且有 Binlog → 提交(保证一致性)
成功提交后崩溃 数据已持久化,正常启动

三、总结:

名称 类型 所属层级 主要用途 是否持久化
Undo Log 日志 InnoDB 回滚、MVCC
Redo Log 日志 InnoDB 崩溃恢复、持久性
Doublewrite Buffer 安全机制 InnoDB 防止页断裂
Change Buffer 缓冲结构 InnoDB 延迟二级索引更新 ❌(数据最终落盘)
Error Log 日志 Server 层 记录 InnoDB 错误
Transaction System / Rollback Segments 内部结构 InnoDB 事务管理元数据
相关推荐
q***581910 分钟前
【SQL】MySQL中的字符串处理函数:concat 函数拼接字符串,COALESCE函数处理NULL字符串
数据库·sql·mysql
懒羊羊不懒@15 分钟前
【MySQL | 基础】多表查询
数据库·sql·mysql
百***69723 分钟前
redis 使用
数据库·redis·缓存
mit6.82425 分钟前
[Column] 构建十亿/s级DB | 索引DB&RTDB | Kafka 为中心 | Rust 构建引擎
数据库
q***05644 分钟前
在Mysql环境下对数据进行增删改查
数据库·mysql
爬山算法1 小时前
Redis(124)Redis在电商系统中的应用有哪些?
数据库·redis·缓存
武子康1 小时前
Java-170 Neo4j 事务、索引与约束实战:语法、并发陷阱与速修清单
java·开发语言·数据库·sql·nosql·neo4j·索引
数据库学啊2 小时前
靠谱的时序数据库哪家技术强
数据库·时序数据库
Wang's Blog2 小时前
MySQL: 存储引擎深度解析:CSV与Archive的特性、应用与实战演示
数据库·mysql
q***07143 小时前
Spring Boot 从 2.7.x 升级到 3.3注意事项
数据库·hive·spring boot