【MySQL修炼篇】一文讲透事务ACID背后的真正功臣日志三剑客Redo Log Undo Log Binlog实战解析MySQL 能实现事务的 ACID99%的人都会背原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability但真正扛起这四个特性的是 InnoDB 的日志三剑客Redo Log重做日志—— 负责持久性Durability和崩溃恢复Undo Log回滚日志—— 负责原子性和隔离性MVCCBinlog归档日志—— 负责主从复制和时间点恢复属于Server层缺了任何一个事务都站不住脚。下面我们用最硬核的方式一步步把它们拆穿给你看。一、事务到底经历了什么—— 经典更新语句全过程updateusersetbalancebalance-100whereid1;假设 balance 原值为 1000事务开始后执行这条语句InnoDB 内部到底干了什么先把 id1 的行从磁盘读到内存Buffer Pool找到这一页检查事务隔离级别默认 REPEATABLE READ生成 ReadView在内存中把 balance 改成 900生成 Undo Log旧值 1000用于回滚和MVCC生成 Redo Log记录“把 balance 物理改成 900”把内存页标记为 Dirty Page事务提交时写 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 × 22024年后建议 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 这么快因为它实现了 WALWrite-Ahead Logging先写日志 → 提交成功 → 后台慢慢刷脏页Checkpoint没有 Redo Log更新必须直接刷磁盘性能直接崩。实战查看当前 redo log 使用情况showengineinnodbstatus\G------------------------LOG------------------------Log sequence number231308424592-- 当前lsnLog flushed upto231308424580-- 已刷到磁盘的lsnLastcheckpointat231300000000-- 上次checkpoint位置# 如果 Log sequence number - Last checkpoint at 接近 innodb_log_file_size 总和# 说明 redo log 快写满了会触发同步刷脏页性能下降2. Undo Log回滚日志—— 原子性 MVCC 的幕后英雄位置默认在 ibdata1 系统表空间5.7前5.7 可独立 undo tablespace逻辑日志记录旧版本数据用途两大事务回滚MVCC 多版本并发控制可重复读的核心每条更新语句都会生成 undo log保存旧值 trx_id roll_pointer查看 undo log 使用情况selectcount(*)frominformation_schema.innodb_trx;-- 当前活跃事务showvariableslikeinnodb_undo_tablespaces;-- 推荐设为 3~16实战长事务会导致 undo log 暴涨占用大量空间甚至撑爆表空间-- 危险千万别在生产这么干begin;select*frombig_tablewhereid1;-- 然后几个小时不提交......-- 这段时间所有更新这个行的语句都会生成新版本undo log 疯狂增长3. Binlog二进制日志—— 主从复制的灵魂属于 Server 层所有引擎都有MyISAM也有逻辑日志记录 SQL 语句或行变化格式三种STATEMENTSBR、ROWRBR最常用、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_commit2 刷爆QPS binlog_rows_query_log_events ON # 便于排查问题三、崩溃恢复时三剑客如何通力合作MySQL 崩溃重启后InnoDB 会执行 Crash Recovery从 Redo Log 最后一次 Checkpoint 开始重放所有 Redo Log包括未刷盘的脏页操作对于已经 commit 但还没刷盘的事务Redo Log 有 prepare commit → 正常重做对于已经写 binlog 但没 commit 的事务Redo Log 只有 prepare → 会回滚保证一致性对于写了 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保证了 DDurability—— 崩溃不丢数据Undo Log保证了 AAtomicity IIsolation/MVCCBinlog保证了主从复制和最终一致性两阶段提交保证了 Redo Log 与 Binlog 的一致性 → 真正实现 CConsistency没有这三把剑事务就是空中楼阁。重阳老哥把这篇发给你的后端兄弟们让他们彻底明白MySQL 的事务 ACID从来不是天上掉下来的而是这三份日志用命换来的看完这篇下次再有人问你“为什么 innodb_flush_log_at_trx_commit1 最安全”你直接甩他这张图就行了Redo Logprepare → Binlog → Redo Logcommit这就是 MySQL 事务的命根子。