必须停库操作,因innodb启动时严格校验ib_logfile大小与配置值是否完全一致,不一致则直接中止;动态修改无效,且崩溃后删日志可能导致页损坏。

不能直接删,也不能改完配置就重启——InnoDB 会拒绝启动,报 InnoDB: Error: log file ib_logfile0 is of different size。
为什么改 innodb_log_file_size 必须停库再操作
InnoDB 启动时会校验磁盘上已有的 ib_logfile0 和 ib_logfile1 大小是否与 my.cnf 中的 innodb_log_file_size 一致。不一致就直接 abort,不会自动覆盖或重建。
- 哪怕只差 1 字节,也会失败;
ls -lh ib_logfile*看到的大小必须和配置值完全相等 -
SET GLOBAL innodb_log_file_size = ...是无效的——该变量不可动态修改 - 如果 MySQL 是
kill -9或崩溃退出,日志文件可能处于中间状态,此时删掉再启库,InnoDB 可能报Database page corruption - 真正安全的前提是:error log 最后一行有
mysqld: Shutdown complete
正确的调整流程(MySQL 8.0.29 及以前)
这是目前绝大多数生产环境仍在用的方式,步骤缺一不可:
- 先执行
SET GLOBAL innodb_fast_shutdown = 0,确保所有脏页刷盘、日志落盘 - 用
mysqladmin shutdown或systemctl stop mysqld正常关闭服务 - 确认进程已退出:
ps aux | grep mysqld应无残留 - 备份原日志:
mv ib_logfile0 ib_logfile0.bak、mv ib_logfile1 ib_logfile1.bak(别用rm) - 编辑
/etc/my.cnf,在[mysqld]段写入新值,例如:innodb_log_file_size = 1G - 启动 MySQL:
systemctl start mysqld——InnoDB 检测不到匹配的日志文件,会自动创建两个新大小的文件
MySQL 8.0.30+ 支持在线调整?别信太快
8.0.30 确实引入了动态调整重做日志大小的能力,但仅限于“增大”,且有硬性前提:
- 必须满足
innodb_dedicated_server = ON(默认 OFF),否则命令ALTER INSTANCE ROTATE INNODB MASTER KEY不生效 - 增大操作实际是追加新日志段,旧段仍保留直到 checkpoint 完成,总空间是“旧+新”,不是替换
- 不支持缩小;也不支持调整
innodb_log_files_in_group数量 - 生产环境建议仍走传统停库流程——可控、可回滚、无需验证引擎行为边界
调多大才算合适?看写入量,不是拍脑袋
经验值是“覆盖 1 小时左右的 Redo 写入量”,太大拖慢崩溃恢复,太小导致频繁 checkpoint 压垮 I/O:
- 用
SHOW ENGINE INNODB STATUS抓两次Log sequence number,间隔 60 秒,算差值 ÷ 1024 ÷ 1024 得 MB/min - 乘以 60 得出理论小时吞吐,再上浮 20% 作为目标
innodb_log_file_size - 注意:总 Redo 容量 =
innodb_log_file_size × innodb_log_files_in_group(默认为 2),别只调单个文件却忽略组数 - 常见安全值范围是 512M~2G;超过 4G 要格外关注恢复时间,尤其是主从延迟敏感场景
最容易被跳过的一步是确认 shutdown 是否 clean——很多人看到 systemctl stop 返回 success 就以为完事了,其实 error log 才是唯一可信依据。没看到 Shutdown complete,就别碰 ib_logfile*。











