redo log保障事务持久性,以物理日志记录数据页变更,支持崩溃恢复与wal优化;undo log保障原子性与mvcc,以逻辑日志保存前镜像,支撑回滚与多版本读。二者协同实现acid,是innodb事务核心基石。

调 redo log 和 undo log 不是为了“堆参数”,而是让日志行为贴合高并发写入的真实负载——重点在减少 checkpoint 频率、加速 purge 清理、避免长事务卡死版本链。
Redo Log:控大小、稳刷盘、避争抢
高并发写入下,redo log 小了会频繁 checkpoint,引发脏页集中刷盘,I/O 波动大;大了又拖慢崩溃恢复。关键不是盲目拉高,而是让日志空间撑住 30 分钟以上写入量:
- 单个文件设为 1G~2G(MySQL 8.0+ 支持在线调整),总大小控制在 2G~4G,目标是
Log sequence number与Last checkpoint at的差值稳定在 30 分钟以上(通过SHOW ENGINE INNODB STATUS查看) -
innodb_flush_log_at_trx_commit设为 2(写 OS cache,每秒 fsync)——SSD/NVMe 场景下实测丢数据概率极低,吞吐比设为 1 提升 3~5 倍;金融类核心链路仍用 1 - 把
ib_logfile*单独放在 SSD 路径(用innodb_log_group_home_dir指定),不和数据文件、undo 文件混放,避免 I/O 竞争
Undo Log:砍大小、开截断、盯长事务
并发更新多时,undo 不是越大会越好——它直接拖慢 MVCC 查询和 purge 效率。真正瓶颈常是单个 undo 表空间膨胀后扫描变慢,而非总空间不足:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
innodb_max_undo_log_size设为 128M~256M(即 134217728~268435456),防止单个 undo 文件“一枝独大”,提升 truncate 和 purge 效率 - 必须开启
innodb_undo_log_truncate = ON(MySQL 5.7+ 默认开),否则调小上限也无效;观察INNODB_METRICS中undo_log_truncations是否持续增长 - 每天定时查长事务:
SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), TRX_STARTED)) > 60,超 60 秒未提交的立即告警干预——这是 undo 堆积的根源,调参治标,杀长事务才治本
协同要点:Buffer Pool 与日志节奏对齐
redo 和 undo 的效率高度依赖 Buffer Pool 的行为。高并发写入时,若 buffer pool 太小或刷脏策略太激进,会反向加剧 redo 切换和 undo 滞留:
-
innodb_buffer_pool_size至少占物理内存的 70%,确保多数热数据常驻内存,减少随机读放大 undo 版本链遍历开销 -
innodb_max_dirty_pages_pct可适度提高到 75~80,配合 redo log 大小,让脏页刷新更平滑,避免 checkpoint 突刺式刷盘 -
innodb_purge_threads设为 4(默认 1),加快 undo 记录清理速度,尤其在大批量 UPDATE/DELETE 场景下效果明显
别踩的坑:这些操作没效果甚至危险
有些常见动作看似合理,实际对高并发写入帮助很小,还可能引入风险:
- 盲目增加
innodb_log_files_in_group(比如设成 4 或 8)——不会线性提升并发写能力,反而延长 recovery 时间,保持默认 2 即可 - 调小
innodb_undo_tablespaces(如从 128 改成 4)——该参数只影响文件个数,不控制单个大小;值过小反而导致多个 undo 段挤在同一文件,加剧内部锁争用 - 不关
innodb_fast_shutdown就直接删 ib_logfile* 重启——旧日志可能被截断,导致宕机后无法完整恢复
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










