MySQL redo log 与 binlog 刷盘选项怎么配合
来源:17golang原创
时间:2026-11-14 03:20:14 365浏览 收藏
使用 InnoDB 且开启 binlog 时,要求已提交事务尽可能可靠地持久化,应把 innodb_flush_log_at_trx_commit=1 与 sync_binlog=1 配合使用,通常称为“双 1”。前者约束 redo log 的提交刷盘,后者约束 binlog 的同步;只把其中一个设为 1,不能替代另一份日志的持久化保证。
双 1 仍依赖操作系统与存储设备如实完成同步,也不代表已经有备份或副本已应用事务。本文围绕 MySQL 8.4 文档说明日志存储、提交与恢复取舍。官方参数入口:https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html;binlog 参数入口:https://dev.mysql.com/doc/refman/8.4/en/replication-options-binary-log.html。
数据来源:同一事务为什么需要两份日志
redo log 属于 InnoDB 的恢复机制,记录用于恢复数据页修改的信息;binlog 位于 MySQL 服务层,记录用于复制和基于备份的增量恢复的变更事件。它们记录同一事务的不同方面,不是互相替代的两份普通文本备份。
提交时不要求把该事务修改的所有数据页立即写回磁盘。日志的持久化与脏页后台写回是不同工作,因此讨论这两个选项时,“刷盘”主要指对应日志的同步,不能据此推导数据页已经全部落盘。

持久化边界:write 不等于已经断电可恢复
日志仍在进程内存、已经写入操作系统缓存、已经同步到持久存储,是不同状态。mysqld 进程退出与整个操作系统崩溃也不是同一种故障。只说“写了日志”不足以判断断电后能保留什么。
| redo 选项值 | 基本行为 | 放宽的边界 |
|---|---|---|
| 1 | 每次提交要求日志写入并同步到磁盘 | 仍依赖底层同步可靠性 |
| 2 | 提交时写出日志,周期性同步到磁盘 | 写入系统缓存不等于抵御系统崩溃或断电 |
| 0 | 周期性写出并同步日志 | 未写出内容还可能因进程异常退出丢失 |
周期通常由 innodb_flush_log_at_timeout 控制,默认值为 1 秒;调度与其他内部活动会影响实际间隔。不能把 0 或 2 简化成“严格最多丢一秒”,更不能用事务数或固定金额描述可接受损失。
| sync_binlog | binlog 同步策略 | 含义 |
|---|---|---|
| 1 | 提交前执行同步,组提交可以共享同步 | 严格持久化的配套选项 |
| 0 | MySQL 不主动同步,交由操作系统处理 | 不是每秒同步的开关 |
| N,大于 1 | 累计 N 个 binlog 提交组后同步 | N 是提交组数,不是秒数,也不一定是事务数 |
存储组合:先确定允许丢失哪一段
双 1 是要求本机日志持久性及 binlog 一致性时的基线。若 redo 为 1、sync_binlog 为 0,不能因为 InnoDB 日志可靠就承诺复制或增量恢复链中的 binlog 完整;若 redo 为 2、sync_binlog 为 1,也不能因为 binlog 同步了就宣称 InnoDB 具有同样的提交持久性。
放宽参数可能减少提交同步开销,但收益取决于存储延迟、并发与事务大小。它是把已确认事务的持久化边界向后移动,不是无成本加速。可重新生成的临时数据与不可重复的业务写入,需要不同的恢复目标,不宜照抄同一组合。
提交与恢复:两阶段协调和组提交各解决什么
开启 binlog 的 InnoDB 事务提交,可以用 redo prepare、binlog 记录及同步、引擎 commit 的协调关系来理解。恢复时需要结合日志决定处于准备状态事务的结局。这不是“redo 和 binlog 各写完就自然一致”,也不意味着每个阶段都机械对应一次独立 fsync。
组提交允许多个事务分摊日志同步工作。因此双 1 不等于“每提交一个事务必然发生两次不可共享的磁盘同步”。另一方面,组提交不会把 sync_binlog=0 变成已经持久化,也不能替代底层存储的同步保障。

日志保证与客户端确认也要区分:客户端在 COMMIT 附近断线,可能无法确定事务是否已经提交。不能看到连接错误就无条件重做一遍写入,应让业务通过幂等标识和状态查询处理不确定结果。双 1 不会消除网络确认的不确定性。
读取当前配置,再制定调整与清理策略
先读取实际运行值,避免只看配置文件;下面的查询不修改服务器。它也把 binlog 是否开启放在一起展示。
-- 读取实际生效值;log_bin 为关闭时,binlog同步参数不能凭空生成日志。
SELECT
@@GLOBAL.log_bin AS binlog_enabled,
@@GLOBAL.innodb_flush_log_at_trx_commit AS redo_commit_policy,
@@GLOBAL.innodb_flush_log_at_timeout AS redo_flush_interval_seconds,
@@GLOBAL.sync_binlog AS binlog_sync_groups;
如果已有开启 binlog 的实例要采用双 1,可以在其配置管理中表达如下意图。这个片段不是完整服务器配置,也不负责开启 binlog;应用变更的时机、权限与重启方式由现有部署方式决定。
[mysqld]
# redo提交持久化与binlog同步配套配置,不单独放宽另一项。
innodb_flush_log_at_trx_commit=1
sync_binlog=1
评估性能时比较同一负载下的提交延迟分位数、吞吐量和日志 I/O 等待,同时记录恢复目标。不要只因一次平均延迟下降就接受丢失窗口。本文没有运行基准,也不提供通用提速比例。
清理策略方面,不要手工删除 redo 文件或直接删除仍需用于复制、备份恢复的 binlog 来“减少刷盘”。日志保留与容量管理是另一组配置目标,调整这两个同步选项不会替你建立完整恢复链。
双 1 能保证任何硬件故障都不丢数据吗?
不能。底层若错误报告同步完成,或者存储介质损坏,参数值本身无法提供保证。它表达的是数据库要求的持久化策略。
sync_binlog=100 表示每一百个事务吗?
严格说是每一百个 binlog 提交组;一个组可能包含多个事务,不能据此准确界定损失条数。
主库双 1 是否意味着副本已追平?
不是。这两个参数针对对应实例的日志持久化;复制接收、应用进度及切换策略还需分别考虑。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习