设为2仍慢的主因是sync_binlog=1导致双重落盘,需同步设为0或1000;且必须关闭autocommit、批量插入、禁用约束检查才能真正提速。

innodb_flush_log_at_trx_commit 没有“平衡”的中间态,只有明确取舍:值为 1 才能扛住断电不丢数据;设为 0 或 2 就等于主动接受某种确定性丢失。
为什么设成 2 还是慢?先查 sync_binlog
常见错误现象:调了 innodb_flush_log_at_trx_commit = 2,但 INSERT 延迟没降多少,iostat -x 1 显示 %util 持续 100%。
- 根本原因往往是
sync_binlog = 1在抢磁盘:binlog 和 redo log 各自 fsync,双重落盘 -
sync_binlog = 0+innodb_flush_log_at_trx_commit = 2是写密集型业务最现实的折中组合 - 若必须开 binlog(如主从),又想保一致性,只能选
sync_binlog = 1+innodb_flush_log_at_trx_commit = 1,但得确认 SSD 是否带 PLP(掉电保护)——否则fsync可能不真落盘
批量插入时只改 innodb_flush_log_at_trx_commit 没用
这个参数只管日志刷盘开销,真正卡住插入性能的,是自动提交、单条 INSERT、索引校验这些环节。
- 必须关
autocommit:SET autocommit = 0,再用INSERT INTO ... VALUES (), (), ()批量提交 - 临时禁用约束检查(仅限可信数据):
SET unique_checks = 0、SET foreign_key_checks = 0,导入完再开 - 单独设
innodb_flush_log_at_trx_commit = 0几乎无效:没关autocommit,每条 INSERT 仍是独立事务,照样走默认刷盘逻辑
怎么验证改生效了?别只看 TPS
文档说的“值为 2 每秒刷一次”是理想情况,实际行为得看监控指标,不是靠猜。
- 关键看
Innodb_os_log_fsyncs:值为 1 时应 ≈ 每秒事务数;值为 2 或 0 时应 ≈ 1(每秒一次后台 fsync) - 再对比
Innodb_os_log_written增速:值为 0 时它会明显滞后于实际写入量,说明日志确实在 buffer 里堆着 - 如果
Innodb_os_log_fsyncs高频触发(比如每秒几十次),说明你可能漏关了autocommit,或者应用层在频繁 COMMIT
fsync,但某些 SATA SSD 即使开了 innodb_flush_log_at_trx_commit = 1,若没 PLP,断电后依然丢数据——这时“安全”只是假象。











