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 之后加载因而优先级更高;改参数前先确认改动落在哪一层,避免重启后行为与预期不符。