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 事务管理元数据
相关推荐
金仓拾光集2 小时前
筑牢风控生命线:金仓数据库替代MongoDB,重构证券融资融券业务的数据基石
数据库·mongodb·信创·1024程序员节·kingbasees·国产化替代
枫叶梨花2 小时前
实战:将 Nginx 日志实时解析并写入 MySQL,不再依赖 ELK
mysql·nginx·elk
那我掉的头发算什么2 小时前
【数据库】navicat的下载以及数据库约束
android·数据库·数据仓库·sql·mysql·数据库开发·数据库架构
纪伊路上盛名在2 小时前
如何批量获取蛋白质序列的所有结构域(domain)数据-2
数据库·人工智能·机器学习·统计·计算生物学·蛋白质
tuokuac3 小时前
虚拟机挂起,重启后主机连接不上虚拟机docker中的mysql?(docker网络状态假死)
网络·mysql·docker
2301_772093564 小时前
高并发webserver_interview
运维·服务器·数据库·后端·网络协议·mysql·wireshark
大G的笔记本5 小时前
MySQL 大表查询优化、超大分页处理、SQL 慢查询优化、主键选择
数据库·sql·mysql
Lear5 小时前
Redis 持久化机制
数据库
儒道易行5 小时前
【攻防实战】Redis未授权RCE联动metasploit打穿三层内网(上)
数据库·redis·网络安全·缓存
爱考证的小刘6 小时前
MySQL OCP认证、Oracle OCP认证
mysql·oracle·oracle数据库·oracle认证·mysql自学·mysql题库·oracle学习