因InnoDB启动时校验redo log文件头信息(如日志序列号、checksum、大小),直接拷贝会导致校验失败报错;必须停库→删旧文件→改配置指向新路径→重启由InnoDB自动重建。

为什么不能直接移动 ib_logfile0/ib_logfile1
MySQL启动时会校验重做日志文件的头信息(包括日志序列号、checksum、文件大小等),如果直接把 ib_logfile0 和 ib_logfile1 拷贝到新路径,再改配置指向它,mysqld 会拒绝启动,并报错:InnoDB: Error: log file ./ib_logfile0 is of different size 或更隐蔽的 Invalid log file size。这不是权限或路径问题,是 InnoDB 内部一致性保护机制——日志文件必须由它自己按当前参数初始化生成。
正确迁移 redo log 到 NVMe 的三步操作
本质是“停库 → 清旧 → 换路径 → 启动重建”,不是搬运文件:
- 确认当前配置:
SHOW VARIABLES LIKE 'innodb_log_group_home_dir';,默认是.(即 datadir 下) - 停 MySQL:
sudo systemctl stop mysql,并用ps aux | grep mysql确保无残留进程 - 删旧日志:
rm -f /var/lib/mysql/ib_logfile*(路径按你实际datadir调整) - 修改配置文件(如
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf):innodb_log_group_home_dir = /nvme/mysql-redo/
注意:该路径必须已存在、属主为mysql:mysql、且挂载时加了noatime,nobarrier - 启动:
sudo systemctl start mysql,InnoDB 会自动在新路径下创建符合innodb_log_file_size的ib_logfile0和ib_logfile1
迁移到 NVMe 后必须同步调的两个关键参数
只换路径不调参,等于白搬。NVMe 的低延迟特性需要配套配置才能释放:
-
innodb_log_file_size:建议设为 512M~1G(总容量控制在 1G~4G)。NVMe 能轻松扛住大日志写入,避免频繁 checkpoint;但别设成 2G 单个——异常重启后恢复扫描太慢,可能超时 -
innodb_flush_method:在 NVMe 上优先用O_DIRECT,绕过 page cache 减少内存拷贝;但必须满足:服务器独占、内存 ≥64G、未用 LVM/云盘虚拟层;否则反而触发额外 IO 路径,或引发 RSS 暴涨 OOM
验证是否生效:SHOW ENGINE INNODB STATUS\G 查看 LOG 部分的 Log sequence number 和 Last checkpoint 是否在新路径下持续推进;同时 ls -lh /nvme/mysql-redo/ib_logfile* 确认文件大小与配置一致。
容易被忽略的挂载陷阱
NVMe 设备挂载时若漏掉关键选项,性能可能打五折:
- 必须加
noatime:redo log 是纯顺序写,记录访问时间毫无意义,还多一次元数据更新 - 必须加
nobarrier(或现代内核下的barrier=0):NVMe 自带断电保护(PLP),禁用 barrier 可省掉一次强制刷写指令 - 避免用
ext4默认 mount 选项(如data=ordered);推荐显式指定:mount -t ext4 -o noatime,nobarrier,errors=remount-ro /dev/nvme0n1p1 /nvme/mysql-redo
最常踩的坑是:路径迁过去了,df -h 显示挂对了,但忘了检查 mount | grep nvme 输出里有没有 noatime,nobarrier —— 这类隐性配置缺失,会让 redo log 写入延迟从 100μs 回退到 500μs 以上。


















