redo log 和 undo log 配置需分离路径、控制生命周期、匹配硬件:redo 建议总大小2~8gb(如2g×2),置于独立nvme ssd;undo 必须设innodb_undo_directory到独立ssd并开启innodb_undo_log_truncate,配合innodb_purge_threads=8与innodb_purge_rseg_truncate_frequency=32防膨胀。

Redo Log 和 Undo Log 的存储参数不能只调大小,关键在分离路径、控制生命周期、匹配硬件能力。MySQL 8.0 默认配置在高并发或大事务场景下极易触发日志写满、purge 延迟、磁盘争用等问题。
如何为 Redo Log 选择合适的 innodb_log_file_size 和存储位置
Redo Log 是顺序写、循环覆盖的物理日志,innodb_log_file_size 过小会导致频繁 checkpoint 和 log 切换,拖慢大事务提交;过大则延长崩溃恢复时间。生产环境建议总大小(innodb_log_file_size × innodb_log_files_in_group)控制在 2GB~8GB 之间:
- OLTP 主流负载:设
innodb_log_file_size = 2G,innodb_log_files_in_group = 2(总 4G),平衡性能与恢复速度 - 金融/强一致性系统:可设为
4G × 2(总 8G),但必须确保磁盘延迟 ≤ 1ms(推荐 NVMe SSD) -
innodb_log_file_size修改必须停机:先执行SET GLOBAL innodb_fast_shutdown = 0,再关闭 mysqld,手动删除ib_logfile0和ib_logfile1,更新 my.cnf 后重启 - 不要把 redo log 和数据文件放在同一挂载点——尤其是 ext4/XFS 默认 journal 也会争用磁盘带宽
为什么必须将 Undo Log 移出系统表空间并启用自动截断
MySQL 8.0 默认启用独立 undo 表空间,但若未显式配置 innodb_undo_directory,undo 仍会写入系统表空间(ibdata1),导致无法清理、膨胀不可控。真实问题是:MVCC 要求旧版本数据长期保留,而 purge 线程跟不上时,undo 就越积越多。
- 务必设置
innodb_undo_directory = /data/mysql/undo/(需提前chown mysql:mysql并确保是独立 SSD 分区) - 开启
innodb_undo_log_truncate = ON(MySQL 8.0+ 默认已开),否则innodb_max_undo_log_size形同虚设 -
innodb_max_undo_log_size建议设为2147483648(2G),太大导致截断不及时,太小引发高频 purge 压力 - 确认
innodb_undo_tablespaces已废弃(8.0.3+),无需配置;旧值残留可能干扰初始化
innodb_purge_threads 和 innodb_purge_rseg_truncate_frequency 怎么协同防膨胀
Undo 日志不是提交就删,而是由 purge 线程异步回收。默认 4 个 purge 线程在高并发写入下常成瓶颈,表现为 SHOW ENGINE INNODB STATUS 中的 PURGE DONE 滞后、History list length 持续攀升。
-
innodb_purge_threads推荐设为8(16 核以下机器),超过 CPU 核数一半反而增加调度开销 -
innodb_purge_rseg_truncate_frequency控制 purge 线程每多少次操作检查一次回滚段是否可截断,默认 128 太保守;设为32可加快释放,但别低于 10(否则 CPU 占用突增) - 配合监控
INFORMATION_SCHEMA.INNODB_METRICS中的purge_truncate_count和purge_undo_log_pages,验证截断是否生效
真正难处理的不是参数本身,而是 undo 生命周期和长事务的耦合——一个运行 2 小时的 SELECT 查询,就能让所有相关 undo 版本全部锁住不释放。所以配置再优,也得配合 innodb_lock_wait_timeout 和定期 kill idle transaction 的运维机制。











