log_sys->mutex 是 InnoDB 事务日志路径上不可绕过的全局单点锁,所有 redo 写入必须争抢它;其争用导致线程挂起、QPS 下降,调大 innodb_log_buffer_size 和调整 innodb_flush_log_at_trx_commit 可缓解,而增大 innodb_log_file_size 无效。

log_sys->mutex 是什么,为什么所有写入都卡在这把锁上
这把锁不是可选开关,而是 InnoDB 事务日志路径上绕不开的临界区入口。只要事务产生 redo(哪怕只改一个字段),就必须抢 log_sys->mutex:分配 buffer 空间 → 拷贝日志内容 → 更新内存 LSN → 判断是否刷盘。它不按事务拆分、不按页隔离,是全局单点。
常见错误现象包括:SHOW ENGINE INNODB STATUS 中大量线程挂起在 log_write_up_to 或 log_flush_up_to;OS WAIT ARRAY 显示自旋等待该 mutex;QPS 超过 2000 后吞吐明显下降,但 CPU 和磁盘 I/O 并不高。
innodb_log_buffer_size 太小会直接放大锁争用
buffer 小 → 容易满 → flush 更频繁 → log_sys->mutex 抢得更勤。默认 16MB 在高并发批量写入下极易触发溢出,表现为 Innodb_log_waits 持续 > 0。
- Java 应用用
executeBatch()插入 1 万行,若 buffer 仍是 16MB,很可能每个 batch 都触发一次 flush,全程被锁卡住 - 合理值应按写入吞吐反推:用
SHOW GLOBAL STATUS LIKE 'Innodb_os_log_written'每 30 秒采样,算出每秒平均字节数,再 × 60 × 2 得到建议 buffer 大小 - 生产环境常见有效值是 64MB,而非盲目调大
innodb_log_file_size
innodb_flush_log_at_trx_commit=1 是锁持有时间拉长的主因
默认值 1 要求每次 COMMIT 都 fsync 到磁盘,I/O 延迟直接延长了 log_sys->mutex 持有时间,加剧排队。设为 2 后,日志仅写入 OS 缓存即返回,后台每秒统一刷盘,吞吐可提升 3–10 倍。
但要注意:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 崩溃最多丢 1 秒数据,不能用于金融、订单等强一致性场景
- 必须配合
sync_binlog调整,否则 binlog 与 redo log 可能不一致 - 监控
Innodb_os_log_pending_fsyncs,持续 > 0 说明 OS 缓存积压严重,此时 =2 也可能不够用
为什么调大 innodb_log_file_size 对锁竞争完全无效
innodb_log_file_size 控制的是磁盘上 redo 文件大小,影响 checkpoint 频率和 crash recovery 时间,但完全不参与 log_sys->mutex 的争用路径。
它太小 → checkpoint 太频繁 → 脏页刷盘压力大 → 反向拖慢 log write;但它增大后,并不会减少 mutex 抢占次数,甚至可能因单次刷盘量变大,延长后台 io_thread 工作时间,间接加重锁等待。
真正要算的是写入吞吐与 buffer 容量的匹配度,而不是日志文件总容量。










