设为2是多数业务的平衡点:每次提交仅写入OS page cache,由内核每秒刷盘,MySQL崩溃不丢数据,OS崩溃最多丢1秒事务;但需重启连接生效。

innodb_flush_log_at_trx_commit 设为 2 是多数业务的平衡点
这个参数控制 InnoDB redo log 的刷盘时机,直接决定事务提交时是否强制落盘。设为 1 每次提交都 fdatasync(),安全但慢;设为 0 风险太高,MySQL 崩溃即丢整个 log buffer(默认 16MB);而 2 表示每次提交只写入 OS page cache,由内核每秒刷一次磁盘——MySQL 崩溃不丢数据,OS 崩溃最多丢 1 秒事务。
常见错误是改完就以为生效:执行 SET GLOBAL innodb_flush_log_at_trx_commit = 2 后,已有连接(比如连接池里长期存活的连接)仍沿用旧值。必须触发应用侧重连或滚动重启服务。
- 电商订单、用户注册等场景可接受
2,只要硬件没断电、OS 不 panic,数据就稳 - 金融支付类系统必须用
1,哪怕 IO 翻倍也得扛住 - 开发/压测环境临时切
0可以,但上线前务必改回,否则等于裸奔
sync_binlog 不要设为 0,100~1000 是更稳妥的选择
sync_binlog 控制 binlog 缓冲区写入磁盘的频率。设为 0 表示完全依赖操作系统每 30 秒左右刷一次,崩溃时可能丢大量 binlog,主从复制直接断裂。设为 1 虽然最安全,但每次事务都触发一次磁盘 fsync,IO 压力极大。
生产中更常用的是 100 或 1000:每 N 次事务提交后才刷一次 binlog。这样既大幅降低刷盘次数,又把丢失风险控制在可预期范围内(最多 N 个事务)。注意,N 过大(如 10000)会导致掉电时丢失量不可控,过小(如 10)性能提升不明显。
- 查当前值:
SHOW GLOBAL VARIABLES LIKE 'sync_binlog' - 临时修改:
SET GLOBAL sync_binlog = 100,但重启失效,必须写进my.cnf - 云厂商托管实例(如阿里云 RDS、腾讯云 CDB)可能默认关掉高可靠模式,需手动开启或确认配置已落地
“双1”不是银弹,错配反而放大风险
很多人听说“双1”(innodb_flush_log_at_trx_commit = 1 + sync_binlog = 1)最安全,就盲目照搬。但若底层不配合,它只是个假安全:
- 磁盘开启了 write-back 缓存(
hdparm -W1 /dev/sdX),fdatasync()实际没落盘 - 文件系统挂载时用了
barrier=0或没加data=ordered,fsync 语义被绕过 - MySQL 启动时因配置路径错误或语法问题(比如写成
ON而非1)静默忽略参数,你以为设了,其实还是默认值
真正关键的是验证:进库执行 SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit' 和 SHOW VARIABLES LIKE 'sync_binlog',两个结果都必须是 1,且监控项 Innodb_os_log_fsyncs 和 Syncs_binlog 的每秒增速要匹配你的事务节奏。
增大 innodb_log_file_size 能间接缓解刷盘压力
默认的 innodb_log_file_size 往往只有 48MB~50MB,在高写入负载下容易频繁触发 checkpoint,导致后台大量刷脏页,IO 尖刺频发。把单个日志文件调大到几百 MB 甚至 1GB,能显著拉长 checkpoint 间隔,让刷盘更平滑。
但注意:修改该参数不能在线做,需停库、删旧日志、重启。而且总大小(innodb_log_file_size × innodb_log_files_in_group)不宜超过 4GB,否则 recovery 时间会明显变长。
- 先查当前大小:
SHOW VARIABLES LIKE 'innodb_log_file_size' - 计算合理值:观察
Innodb_os_log_written每秒增长量,乘以 30~60 秒,就是推荐的单文件大小下限 - 别只盯着这个参数——如果
innodb_flush_log_at_trx_commit和sync_binlog还卡在默认值,光调大日志文件作用有限



















