innodb_log_writes和innodb_os_log_written飙升表明redo log高频刷盘,非sql慢导致;每秒innodb_log_writes>1000或innodb_os_log_written增长超2mb即为异常,需结合iotop -h -o和show engine innodb status的log段差值及pending writes交叉验证。

看 Innodb_log_writes 和 Innodb_os_log_written 是否飙升
这两个状态变量直接反映 redo log 的写入频率和总量。如果 Innodb_log_writes 每秒持续 >1000,或 Innodb_os_log_written 每秒增长超 2MB,基本可断定是 log_writer 线程在高频刷盘,而非用户 SQL 导致的写 IO。
执行:
SHOW GLOBAL STATUS LIKE 'Innodb_log_writes';<br>SHOW GLOBAL STATUS LIKE 'Innodb_os_log_written';
- 对比前后 10 秒差值,算出每秒速率,比看绝对值更有意义
- 若该值突增但慢查询日志几乎为空,说明问题不在业务 SQL,而在事务提交节奏或日志策略
- 注意:innodb_flush_log_at_trx_commit=1 时,每个事务 commit 都触发一次
pwrite64写ib_logfile0,小事务密集场景极易打满磁盘写带宽
用 iotop -p $(pgrep mysqld) -H -o -d 1 找出真实写线程
别只盯着 mysqld 进程名——MySQL 内部多个线程独立跑 I/O,log_writer、purge_thread、io_write_thread 都可能成为写盘主力。不加 -H(显示线程)和 -o(仅活跃线程),你会完全错过它们。
- 重点关注 COMMAND 列含
log_writer或写ib_logfile0的线程,TID 对应的 IO> 值高就是它 - 若看到大量
pread64+ibdata1或 undo 表空间文件,History list length 可能已超 100000,purge 跟不上导致持续回滚段写入 -
io_write_thread高 IO 通常对应脏页刷盘,此时要查Innodb_buffer_pool_pages_dirty / Innodb_buffer_pool_pages_total是否 >15%
检查 SHOW ENGINE INNODB STATUS\G 中的 LOG 和 FILE I/O 段
LOG 段里的 LSN 差值和 FILE I/O 段的 pending writes 是关键信号,它们不骗人。
- Log sequence number 和 Last checkpoint at 差值超过
innodb_log_file_size × 2,说明 checkpoint 落后,InnoDB 会强制同步刷脏页,瞬间拉高写 IO - Pending normal aio writes > 0 且持续不归零,代表磁盘写入能力已跟不上后台请求节奏,不是“要不要优化”,而是“必须扩容或调参”
- FILE I/O 段还藏着
os file reads和os file writes的累计值,和iostat -x 1的 r/s、w/s 对得上,才能确认是 MySQL 自身行为,而非 backup/rsync 干扰
为什么 slow_query_log 里没几条慢 SQL,但磁盘写爆了
因为慢日志只记录执行时间长的 SQL,而高频小事务、后台 purge、redo 刷盘、双写(doublewrite)这些操作既合法又高效,却全都不进慢日志——但它们每一笔都实实在在往磁盘发写请求。
- 典型场景:订单系统每秒数百笔支付,每笔开事务+insert+commit,innodb_flush_log_at_trx_commit=1 → 每秒几百次
pwrite64写ib_logfile0 - 另一个隐藏点:
innodb_doublewrite=ON时,每次刷脏页会额外写 doublewrite buffer 文件,IO 请求翻倍却不体现在任何 SQL 日志里 - 临时表落盘(
Created_tmp_disk_tables飙升)也会触发大量写,但它属于 server 层行为,InnoDB 状态里看不到痕迹,得靠SHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables'单独盯











