答案:避免i/o调度冲突导致延迟飙升。innodb重做日志(ib_logfile0/1)为顺序写入,数据文件(.ibd)为随机读写,共用磁盘会迫使i/o调度器频繁切换模式,尤其在高并发update/insert时引发log pending writes积压及os i/o延迟升高。

为什么日志必须放在独立磁盘上
InnoDB 的 ib_logfile0 和 ib_logfile1 是纯顺序写入,但和数据文件(.ibd)的随机读写混在一块磁盘时,I/O 调度器会被迫频繁切换模式,导致延迟飙升。尤其在高并发 UPDATE/INSERT 场景下,你会看到 SHOW ENGINE INNODB STATUS 中 log pending writes 持续不为 0,或 OS file reads/writes 的平均延迟明显升高。
如何配置 innodb_log_group_home_dir
这个参数指定 redo log 文件的存放路径,它必须是绝对路径,且 MySQL 进程要有读写权限。修改前需停机,否则启动失败。
- 先创建专用目录并赋权:
mkdir -p /ssd/mysql-redo<br>chown mysql:mysql /ssd/mysql-redo
- 编辑
my.cnf,添加或修改:[mysqld]<br>innodb_log_group_home_dir = /ssd/mysql-redo
- 停止 MySQL,**手动删除旧日志文件**(
ib_logfile0,ib_logfile1),再启动 —— MySQL 会按当前innodb_log_file_size自动重建。 - 确认生效:
SELECT @@innodb_log_group_home_dir;,并检查该路径下是否生成了新日志文件。
SSD/NVMe 上还要注意什么
即使用了 SSD,若挂载在普通 SATA 接口或被其他进程大量占用,性能仍会打折扣。几个关键点:
- 避免使用 NFS 或 CIFS 等网络文件系统 ——
innodb_flush_log_at_trx_commit=1下可能直接卡住连接; - 文件系统选
xfs(比 ext4 更适合大块顺序写),挂载时加noatime,nodiratime; - 禁用 I/O 调度器(特别是 NVMe):
echo none > /sys/block/nvme0n1/queue/scheduler; - 不要把 binlog、slow log、error log 和 redo log 放同一块盘 —— 它们写入节奏不同,会互相干扰。
容易忽略的权限与 SELinux 问题
Linux 发行版(如 CentOS/RHEL)启用 SELinux 后,即使目录权限正确,MySQL 也可能因策略限制无法写入新路径。现象是 MySQL 启动日志里出现类似 Can't create/write to file '/ssd/mysql-redo/ib_logfile0' (Errcode: 13),而 ls -Z 显示目录上下文不是 mysqld_db_t。
- 临时放行(验证用):
setenforce 0; - 永久修复:
semanage fcontext -a -t mysqld_db_t "/ssd/mysql-redo(/.*)?",然后restorecon -Rv /ssd/mysql-redo; - 若用 systemd 启动,还需检查
ProtectHome=true或RestrictAddressFamilies=是否误拦了路径访问。











