Innodb_os_log_pending_fsyncs 持续大于0是redo log刷盘卡住的直接信号;需结合LOG段LSN差值、iostat的%util/await/svctm综合判断磁盘I/O瓶颈。

看 Innodb_os_log_pending_fsyncs 是否持续不归零
这个状态变量是判断 redo log 刷盘是否卡住的最直接信号。值为 0 表示所有日志都已落盘;一旦长期 > 0(比如连续 5 秒以上稳定在 1–10+),说明 OS 缓存里的日志正排队等 fsync(3),而磁盘跟不上节奏。
执行:SHOW GLOBAL STATUS LIKE 'Innodb_os_log_pending_fsyncs';
- 别只查一次——用脚本每秒轮询,观察是否“缓慢爬升后骤降”,这是典型刷盘跟不上+后台集中 flush 的表现
- 如果值偶尔跳到 1 但立刻归零,大概率不是瓶颈,可能是瞬时写入毛刺
- 配合
SHOW ENGINE INNODB STATUS\G中 LOG 段的Log sequence number和Log flushed up to差值看趋势:差值持续拉大 +Innodb_os_log_pending_fsyncs > 0= 铁证
用 iostat -x 1 确认是不是 redo log 所在磁盘被堵死
别只盯着 %util。真正关键的是三个指标同时异常:
-
%util > 80%:设备忙时占比高 -
await > 20ms(SSD)或> 50ms(HDD):单次 I/O 平均等待时间过长 -
svctm却很低(比如
再用 iotop -oP 锁定进程:如果 mysqld 在 WRITE 列持续占满带宽,且目标路径正是 innodb_log_group_home_dir(默认是数据目录),那基本就是它了。
云盘用户特别注意:await 高但吞吐低,很可能是 ESSD 的 burst credits 耗尽,得查云监控里的 IOPS 实际配额使用率。
检查 innodb_log_file_size 是否小到引发连坐式卡顿
日志文件太小不会让你“慢”,而是让你“周期性卡死”。比如 innodb_log_file_size = 48MB,在每秒写入 20MB redo 的业务下,不到 3 秒就满,触发强制 checkpoint —— 这时所有写事务暂停,InnoDB 把脏页刷盘腾空间,表现为每 2–3 秒一次、持续数秒的全库卡顿。
- 查当前值:
SHOW VARIABLES LIKE 'innodb_log_file_size'; - 估算最低需求:用
SHOW GLOBAL STATUS LIKE 'Innodb_os_log_written';每 10 秒采样一次,算出峰值写入速率(B/s),乘以 15×60 得到 15 分钟容量,单个文件建议 ≥ 1GB - 必须停库调整:先
SET GLOBAL innodb_fast_shutdown = 0;,再关 mysqld,删掉ib_logfile0和ib_logfile1,改配置,重启 - 别碰
innodb_log_files_in_group:它只控制文件个数,总容量由 ×innodb_log_file_size决定
验证 innodb_flush_log_at_trx_commit 和 sync_binlog 是否协同失配
设 innodb_flush_log_at_trx_commit = 2 却保留 sync_binlog = 1,等于白调:redo log 虽然只写缓存,但 binlog 还是每事务 fsync,提交照样卡在 binlog 刷盘上。
- 查当前组合:
SELECT @@innodb_flush_log_at_trx_commit, @@sync_binlog; - 安全且有效的搭配只有两种:
–1+1(强一致,但压测常卡)
–2+100或1000(推荐,降低双刷频率) - 改成
2后务必监控Innodb_log_waits:如果该值开始上涨,说明 OS 缓存积压严重,可能需调大innodb_log_buffer_size或检查磁盘本身 - 金融类业务慎用
2:哪怕只有一张资金表,也别碰
真正卡点往往不在参数本身,而在它们之间的耦合关系和磁盘实际承载能力。调参前先确认 innodb_log_group_home_dir 路径是否真落在 SSD 上、权限是否正确、挂载选项是否含 noatime,nobarrier——这些细节漏掉一个,换再快的盘也没用。


















