首页/数据/数据库速查/Binlog 同步刷盘(sync_binlog)与崩溃安全组合
性能与调优57 条

Binlog 同步刷盘(sync_binlog)与崩溃安全组合

双 1 配置(innodb_flush_log_at_trx_commit=1 + sync_binlog=1)是崩溃不丢事务的标配;sync_binlog=0 交给 OS 刷盘,主库高并发时是隐藏瓶颈。

数据库速查数据更新于 2026-10-13

sync_binlog 是什么

sync_binlog 决定 MySQL 何时把 binlog 缓冲区刷到磁盘:取值 1 表示每个事务提交都调用 fsync(MySQL 8.0 默认值),取值 0 交给操作系统决定,取值 N 表示每积累 N 个事务刷一次。它和 innodb_flush_log_at_trx_commit 是一对搭档,只有两者同为 1 的「双 1」组合才保证崩溃不丢已提交事务、不丢复制位点;只盯一个参数判断不了实例的持久化级别。

基本信息

适用版本MySQL 5.7 / 8.0,主库从库都生效
作用域全局变量,修改需 SYSTEM_VARIABLES_ADMIN
取值0=OS 决定;1=每次提交 fsync;N=每 N 个事务 fsync
默认值MySQL 8.0 为 1,5.7 也为 1
搭档参数innodb_flush_log_at_trx_commit

典型使用场景

  • 订单、支付类主库:维持双 1,靠更好的磁盘而不是降参数换吞吐
  • 核对复制安全性:binlog 未落盘就断电,从库可能永远缺失这段事务
  • 压测定瓶颈:把 sync_binlog 改 0 后 QPS 明显上升,说明卡在 fsync 而非 SQL
  • 批量导入窗口:临时放宽换导入速度,结束后立刻改回 1
  • 排查长事务:Binlog_cache 磁盘计数增长说明有大事务在写临时文件
  • 核对备份与下游链路:归档、CDC、binlog 订阅都依赖这段日志不丢
  • 审计合规场景:日志不丢的要求必须落到参数上,而不是只写在制度文档里

查看与调整

查看与调整
SHOW VARIABLES LIKE 'sync_binlog';                    # 确认当前取值
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';  # 搭档参数
SET GLOBAL sync_binlog = 1;                            # 动态生效,重启回落到配置文件
SET PERSIST sync_binlog = 1;                           # 8.0 写入 mysqld-auto.cnf,重启仍生效
SHOW STATUS LIKE 'Binlog_cache%';                      # 磁盘缓存用量飙升说明事务过大
SHOW BINARY LOGS;                                      # 确认 binlog 仍在正常写入
iostat -x 1                                            # 看磁盘 await/util,判断 fsync 压力

取值对照与代价

取值提交行为断电后果
1每次提交 fsync,日志落盘后才返回成功已提交事务不丢,吞吐受磁盘 fsync 能力限制
0交给 OS 刷盘,速度最快可能丢最近若干事务,复制位点也可能回退
N攒够 N 个事务刷一次按批次丢,N 越大丢失范围越大
主从复制场景下 binlog 刷盘还影响复制延迟:主库提交速度被磁盘 fsync 决定时,先看 IO 延迟再谈调参。
把 sync_binlog 从 1 改成 0 是用持久化换吞吐,属于需要业务方确认的取舍;即使放宽 binlog,也建议保持 innodb_flush_log_at_trx_commit=1,避免 InnoDB 内部一致性一起退化。
MySQL 8.0 起 SET PERSIST 会把改动写进 mysqld-auto.cnf,它在 my.cnf 之后加载因而优先级更高;改参数前先确认改动落在哪一层,避免重启后行为与预期不符。

易错点

  • 只调 sync_binlog 不管 redo 参数:崩溃后 InnoDB 自洽但复制位点丢失,从库要重建
  • 把 sync_binlog=0 当纯性能优化上线,断电后丢单且无法从 binlog 找回
  • N 取值过大(如 1000),大事务场景积累大量未刷盘日志,恢复时间被拉长
  • 改完只看 SHOW VARIABLES 就算完:还应确认 SHOW BINARY LOGS 正常且磁盘空间充足
  • 磁盘打满会让 fsync 失败并阻塞提交,sync_binlog=1 的实例必须监控磁盘水位

数据来源与参考

  • MySQL 8.0 Reference Manual: sync_binlog

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌