确认redo log刷盘导致锁等待需满足至少两条:show processlist大量卡在updating/writing to net、innodb_os_log_pending_fsyncs>0长期不归零、log段中log sequence number与log flushed up to差值持续拉大、innodb_log_waits持续增长;innodb_flush_log_at_trx_commit=1非必须改,但高tps下可权衡设为2以平衡性能与安全;ssd需正确挂载(noatime,nodiratime,barrier=0)、启用innodb_use_native_aio、redo路径独立且权限正确;innodb_log_file_size过小会引发前台刷脏,须按1小时峰值redo量×2估算总容量并停库调整。

单纯换SSD不一定能解决 Redo Log 写锁等待,关键得看是不是真被 redo log 刷盘卡住,以及 SSD 的用法对不对。
怎么确认是 redo log 刷盘导致的锁等待?
别一看到 iostat -x 1 的 %util 高就换盘。先抓准现象:
-
SHOW PROCESSLIST里大量事务卡在Updating或Writing to net,但 CPU 和内存不飙 -
SHOW ENGINE INNODB STATUS的LOG段显示Log sequence number和Log flushed up to差距持续拉大(说明刷不及时) -
innodb_os_log_pending_fsyncs> 0 且长期不归零(SHOW GLOBAL STATUS LIKE 'innodb_os_log_pending%') - 监控里
Innodb_log_waits持续增长(每秒有等待)
满足以上至少两条,才值得往下查 redo log 配置和磁盘行为。
innodb_flush_log_at_trx_commit=1 是不是必须改?
默认值 1 确保每次事务提交都 fsync redo log,数据最安全,但也最容易压垮磁盘——尤其当 TPS 超过磁盘 IOPS 极限时。
- 改成
2:redo log 写入 OS page cache 即返回,MySQL 崩溃不丢数据,主机掉电可能丢最多 1 秒事务。性能提升明显,风险可控 - 不建议设为
0:redo log 只留在内存,MySQL 异常重启就丢数据,比2风险高得多 - 改完要配合
sync_binlog调整,否则 binlog 和 redo log 可能不一致
线上业务若允许短暂数据丢失(如日志类、统计类),innodb_flush_log_at_trx_commit=2 是性价比最高的调优点。
SSD 换了还是卡,可能挂载或配置没对
新 SSD 必须正确挂载并启用 O_DIRECT,否则系统缓存会干扰 InnoDB 自己的缓冲逻辑:
- 检查挂载参数:
mount | grep /data确认含noatime,nodiratime,barrier=0(后者仅限企业级 SSD) - 确认
innodb_use_native_aio=ON(Linux 下异步 IO 加速必需) - 验证
innodb_log_group_home_dir是否真指向 SSD 路径(比如/data/ssd/redo/),且 MySQL 用户对该路径有读写权限 - 避免把 redo log 和业务表、binlog 放在同一块 SSD 上——它们的 IO 模式冲突(redo 是顺序小写,业务表是随机读写)
没做这些,换再快的 NVMe 也白搭,IO 请求照样排队。
redo log 文件大小不合理也会引发前台刷脏
innodb_log_file_size 太小会导致 checkpoint 过于频繁,InnoDB 不得不把本该后台做的刷脏页动作推到用户线程里执行,表现为“间歇性卡顿”。
- 计算参考值:总 redo log 容量 ≈ 1 小时内产生的最大 redo 日志量 × 2;单个文件大小 = 总容量 ÷ 2(默认 2 个文件)
- 常见误操作:直接删
ib_logfile*文件再改配置——MySQL 启动会报错,必须先停库、删文件、再改配置、再启库 - 调整后观察
Innodb_log_writes和Innodb_log_waits是否同步下降
这个参数不像 innodb_flush_log_at_trx_commit 那样立竿见影,但它是长期稳定性的基础,容易被忽略。











