【MySQL修炼篇】一文讲透 MySQL 事务 ACID 背后的功臣:日志三剑客实战解析

【MySQL修炼篇】一文讲透事务ACID背后的真正功臣:日志三剑客(Redo Log + Undo Log + Binlog)实战解析

MySQL 能实现事务的 ACID,99%的人都会背:
原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

但真正扛起这四个特性的,是 InnoDB 的日志三剑客

  1. Redo Log(重做日志)—— 负责持久性(Durability)和崩溃恢复
  2. Undo Log(回滚日志)—— 负责原子性和隔离性(MVCC)
  3. Binlog(归档日志)—— 负责主从复制和时间点恢复(属于Server层)

缺了任何一个,事务都站不住脚。

下面我们用最硬核的方式,一步步把它们拆穿给你看。

一、事务到底经历了什么?—— 经典更新语句全过程

update user set balance = balance - 100 where id = 1;

假设 balance 原值为 1000,事务开始后执行这条语句,InnoDB 内部到底干了什么?

  1. 先把 id=1 的行从磁盘读到内存(Buffer Pool),找到这一页
  2. 检查事务隔离级别(默认 REPEATABLE READ),生成 ReadView
  3. 在内存中把 balance 改成 900
  4. 生成 Undo Log(旧值 1000,用于回滚和MVCC)
  5. 生成 Redo Log(记录“把 balance 物理改成 900”)
  6. 把内存页标记为 Dirty Page
  7. 事务提交时:
  • 写 Redo Log(刷到磁盘,fsync)→ 标记 prepare
  • 写 Binlog(刷到磁盘,fsync)
  • 再写 Redo Log(标记 commit)
    → 这就是传说中的两阶段提交(2PC)

只有这三步全部落盘,MySQL 才会返回客户端 OK!

二、日志三剑客深度拆解 + 实战配置

1. Redo Log(重做日志)—— 持久性的真正守护神

  • 位置:默认 ib_logfile0、ib_logfile1(可通过 innodb_log_group_home_dir 修改)
  • 大小:innodb_log_file_size(默认 48MB × 2,2024年后建议 1~4GB)
  • 属于 InnoDB 引擎私有,物理日志(记录“在某个数据页上做了什么修改”)

核心参数实战推荐(8核32G机器,OLTP系统):

innodb_log_file_size = 2G           # 越大越好,建议是 1小时redo日志量
innodb_log_files_in_group = 2
innodb_flush_log_at_trx_commit = 1  # 最安全,推荐生产使用
# 1 = 每次commit都fsync redo log(最慢最安全)
# 0 = 每秒fsync一次(快,有可能丢1秒数据)
# 2 = 每次commit写os cache,每秒fsync(推荐高并发场景)

为什么 Redo Log 能让 MySQL 这么快?
因为它实现了 WAL(Write-Ahead Logging):
先写日志 → 提交成功 → 后台慢慢刷脏页(Checkpoint)

没有 Redo Log,更新必须直接刷磁盘,性能直接崩。

实战查看当前 redo log 使用情况:

show engine innodb status\G
------------------------
LOG
------------------------
Log sequence number          23 1308424592    -- 当前lsn
Log flushed up to            23 1308424580    -- 已刷到磁盘的lsn
Last checkpoint at           23 1300000000    -- 上次checkpoint位置

# 如果 Log sequence number - Last checkpoint at 接近 innodb_log_file_size 总和
# 说明 redo log 快写满了,会触发同步刷脏页,性能下降!

2. Undo Log(回滚日志)—— 原子性 + MVCC 的幕后英雄

  • 位置:默认在 ibdata1 系统表空间(5.7前),5.7+ 可独立 undo tablespace
  • 逻辑日志:记录旧版本数据

用途两大:

  1. 事务回滚
  2. MVCC 多版本并发控制(可重复读的核心)

每条更新语句都会生成 undo log,保存旧值 + trx_id + roll_pointer

查看 undo log 使用情况:

select count(*) from information_schema.innodb_trx;  -- 当前活跃事务
show variables like 'innodb_undo_tablespaces';  -- 推荐设为 3~16

实战:长事务会导致 undo log 暴涨,占用大量空间,甚至撑爆表空间!

-- 危险!千万别在生产这么干
begin;
select * from big_table where id=1;
-- 然后几个小时不提交......
-- 这段时间所有更新这个行的语句都会生成新版本,undo log 疯狂增长

3. Binlog(二进制日志)—— 主从复制的灵魂

  • 属于 Server 层,所有引擎都有(MyISAM也有)
  • 逻辑日志:记录 SQL 语句或行变化
  • 格式三种:STATEMENT(SBR)、ROW(RBR,最常用)、MIXED

推荐配置(2025生产标配):

server_id = 1
log_bin = /data/mysql/binlog/mysql-bin
binlog_format = ROW                 # 必须是ROW!!
expire_logs_days = 14
max_binlog_size = 1G
sync_binlog = 1                     # 最安全,和 redo log 一样每次commit fsync
# 如果不在乎丢最后几条binlog,可设为 1000+,配合 innodb_flush_log_at_trx_commit=2 刷爆QPS
binlog_rows_query_log_events = ON   # 便于排查问题

三、崩溃恢复时,三剑客如何通力合作?

MySQL 崩溃重启后,InnoDB 会执行 Crash Recovery:

  1. 从 Redo Log 最后一次 Checkpoint 开始,重放所有 Redo Log(包括未刷盘的脏页操作)
  2. 对于已经 commit 但还没刷盘的事务:Redo Log 有 prepare + commit → 正常重做
  3. 对于已经写 binlog 但没 commit 的事务:Redo Log 只有 prepare → 会回滚(保证一致性)
  4. 对于写了 commit 但没写 binlog 的事务:重启后会自动提交(5.7+行为)

这就是“到底以谁为准”的终极答案:
redo log 的 commit 标记才是事务是否真正提交的最终标志!

四、生产级最佳实践总结(直接抄走)

# my.cnf 黄金配置(高并发OLTP系统,2025-2026推荐)
[ mysqld ]
innodb_buffer_pool_size = 70% 内存
innodb_log_file_size = 2G
innodb_log_files_in_group = 2
innodb_flush_log_at_trx_commit = 1
innodb_undo_tablespaces = 8

log_bin = /data/mysql/binlog/mysql-bin
binlog_format = ROW
sync_binlog = 1
binlog_rows_query_log_events = ON
server_id = 1337

# 监控必开
innodb_monitor_enable = all
performance_schema = ON

五、一句话总结

  • Redo Log 保证了 D(Durability)—— 崩溃不丢数据
  • Undo Log 保证了 A(Atomicity) + I(Isolation/MVCC)
  • Binlog 保证了主从复制和最终一致性
  • 两阶段提交 保证了 Redo Log 与 Binlog 的一致性 → 真正实现 C(Consistency)

没有这三把剑,事务就是空中楼阁。

重阳老哥,把这篇发给你的后端兄弟们,让他们彻底明白:
MySQL 的事务 ACID,从来不是天上掉下来的,而是这三份日志用命换来的!

看完这篇,下次再有人问你“为什么 innodb_flush_log_at_trx_commit=1 最安全”,你直接甩他这张图就行了:

Redo Log(prepare) → Binlog → Redo Log(commit)

这就是 MySQL 事务的命根子。

文章已创建 4466

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部