MySQL redo log 与 binlog 怎样判断提交顺序
如果把 redo log 和 binlog 简单理解成“谁先写谁就先提交”,很容易在崩溃恢复或主从延迟排查中得到错误结论。更准确的判断方式是:redo log 主要服务于 InnoDB 数据页的崩溃恢复,binlog 主要服务于事务复制和时间点恢复;两者会通过两阶段提交协同,但不是一份可以直接按文件偏移互相排序的日志。
在默认的 binlog_order_commits=ON 下,MySQL 会让事务按照写入 binlog 的顺序向存储引擎发出提交指令。因此,通常可以把 binlog 中事务组的先后看作提交顺序;但 redo log 的 LSN 只能说明 redo 记录在 InnoDB 日志流中的位置,不能单独证明事务已经对外提交。

先把 redo log 和 binlog 放回各自职责
redo log 记录的是 InnoDB 对数据页做修改时产生的恢复信息,核心位置标识是不断增长的 LSN。实例异常退出后,InnoDB 依据 redo log 重放尚未完整落盘的数据页修改。它回答的是“数据页修改如何恢复”,而不是“复制线程应该按什么顺序执行事务”。
binlog 记录的是服务器层面的事务变更,供复制和时间点恢复使用。对事务表而言,事务中的变更通常在提交点附近作为一个事务组写入 binlog。它回答的是“哪些事务应该被复制或重放,以及它们在二进制日志中的排列是什么”。
所以,排查提交顺序时先记住两个边界:
- redo log 的 LSN 是 InnoDB 日志位置,不是事务提交序号。
- binlog 的文件偏移是二进制日志位置,不是 redo log 的 LSN。
一次提交大致经过哪些阶段
对于只涉及 InnoDB 的普通事务,可以用下面的抽象链路理解双写日志:
- 事务修改数据页,并在 InnoDB 日志系统中产生 redo 记录。
- 存储引擎进入 prepare 状态,服务器确认参与事务的存储引擎已经准备提交。
- 服务器将事务内容写入 binlog,组提交时多个事务可能一起完成这一阶段。
- 根据
sync_binlog、innodb_flush_log_at_trx_commit等持久化策略完成相应刷盘动作。 - 服务器向存储引擎发出 commit,InnoDB 之后可以在崩溃恢复中根据 redo 和事务状态判断哪些修改应保留。
这里的“阶段”不是让你拿两个日志文件的时间戳逐条对齐,而是解释为什么恢复时必须同时看服务器层的 binlog 记录和 InnoDB 的 redo/事务状态。某个阶段已经写入缓存,也不代表它已经完成磁盘持久化;某条 redo 记录的 LSN 更大,也不代表对应事务先于另一事务对外可见。
默认配置下怎样判断提交顺序
MySQL 8.4 文档对 binlog_order_commits 的定义很关键:该变量开启时,存储引擎收到的事务提交指令会按事务写入 binlog 的顺序串行化;关闭后,组内事务可能由多个线程提交,从而出现“binlog 排列顺序”和“存储引擎实际提交顺序”不同的情况。
先读取当前配置:
-- 查看影响提交顺序和持久化边界的关键变量
SHOW GLOBAL VARIABLES
WHERE Variable_name IN (
'binlog_order_commits',
'sync_binlog',
'innodb_flush_log_at_trx_commit'
);
判断可以按下面的表来做:
| 观察项 | 能说明什么 | 不能说明什么 |
|---|---|---|
| binlog 中事务的排列 | 服务器写入二进制日志的先后 | 不能直接得到 redo LSN 或磁盘刷盘时刻 |
| redo LSN | InnoDB 日志记录在日志流中的位置 | 不能单独证明事务已经 commit |
| binlog_order_commits=ON | 默认情况下提交指令与 binlog 写入顺序保持一致 | 不能消除组提交、刷盘和复制调度的延迟 |
| binlog_order_commits=OFF | 允许组内并行提交以换取吞吐量 | 不能假设存储引擎提交顺序等于 binlog 顺序 |
用 mysqlbinlog 找到事务在 binlog 中的顺序
需要确认服务器层面的事务排列时,优先使用 mysqlbinlog 查看事务边界、GTID 或 XID,而不是只看文件修改时间。下面命令只负责提取可读的事件,实际文件名和起止位置按现场替换:
# 查看指定 binlog 的事务边界和提交相关事件
mysqlbinlog --base64-output=DECODE-ROWS --verbose \
--start-position=12345 --stop-position=18000 \
/var/lib/mysql/binlog.000123
排查时可以记录三列:事务标识、binlog 文件与起始位置、事务在文件中的前后关系。不要把相邻的 event 位置当成 redo LSN,也不要用操作系统看到的文件 mtime 替代事务提交顺序。组提交可能让一批事务在一次刷盘动作中出现,但它们在 binlog 中仍有自己的排列。
redo log 只能怎样辅助判断
redo log 更适合回答“崩溃恢复需要重放到哪里”和“某个修改是否已经进入 InnoDB 日志链路”。如果现场能拿到 InnoDB 诊断信息,可以把 LSN 作为恢复进度或日志空间推进的指标;但不要据此推导两个事务之间的完整提交顺序。

一个实用的交叉记录方式是:
-- 记录当前实例的提交顺序相关配置,便于和 binlog 采样结果放在一起
SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM performance_schema.global_variables
WHERE VARIABLE_NAME IN (
'binlog_order_commits',
'sync_binlog',
'innodb_flush_log_at_trx_commit'
)
ORDER BY VARIABLE_NAME;
然后将同一时间窗口内的 binlog 事务顺序、复制端接收/执行位置、实例重启时间和 InnoDB 恢复阶段分别记录。这样能区分“事务已经写入 binlog 但副本尚未执行”“事务已经提交但数据页尚未在正常路径刷出”和“恢复阶段根据 redo 重新构造事务状态”这几类现象。
什么时候需要调整 binlog_order_commits
如果业务要求主库和多线程副本严格保持提交历史的一致顺序,保持 binlog_order_commits=ON 更容易解释和排查;如果吞吐量是首要目标,并且组内事务之间没有必须依赖提交先后的关系,可以评估关闭它带来的并行提交收益。
关闭前要特别注意:同一个客户端会话发出的事务仍按该会话的时间顺序提交,但不同会话组成的提交组可能出现 binlog 顺序和实际提交顺序不一致。若多线程副本需要保持提交顺序,还要结合副本侧的提交顺序设置,而不是只改主库一个变量。
最后用一条判断口诀收束
想判断“服务器写入的事务顺序”,看 binlog;想判断“存储引擎恢复需要的修改顺序”,看 redo LSN;想判断“binlog 顺序是否等于提交指令顺序”,看 binlog_order_commits;想判断“数据是否已经可靠落盘”,还必须同时考虑 sync_binlog 和 innodb_flush_log_at_trx_commit。
相关问题
- redo log 的 LSN 越大是不是事务提交越晚?不是,LSN 是 InnoDB 日志流位置,不能单独当作提交序号。
- binlog 文件位置能不能和 redo LSN 直接比较?不能,两者属于不同日志系统。
- 为什么 binlog 顺序和副本执行顺序不一样?复制线程数、并行调度和副本提交顺序配置都可能造成差异。
- 怎样先保证一致性再追求吞吐量?先保持默认提交顺序并记录配置,再用明确的压测结果评估并行提交。
MySQL 不同表使用同名 CHECK 约束为什么报错
- 上一篇
- MySQL 不同表使用同名 CHECK 约束为什么报错
- 下一篇
- MySQL innodb_print_all_deadlocks 怎样把死锁写入错误日志
-
- 数据库 · MySQL | 25分钟前 |
- MySQL mysqldump 怎样只导出表结构和触发器
- 376浏览 收藏
-
- 数据库 · MySQL | 34分钟前 |
- MySQL 不同表使用同名 CHECK 约束为什么报错
- 123浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL 修改列为 INVISIBLE 后为什么旧视图仍返回该列
- 300浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL invisible index 使用 SET_VAR 临时启用的单条查询配置方法
- 111浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL MATCH AGAINST 怎样控制布尔全文检索的前缀匹配
- 108浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · 性能监控 · InnoDB · mysql INFORMATION_SCHEMA INNODB_METRICS InnoDB监控 innodb_monitor_enable
- MySQL INFORMATION_SCHEMA.INNODB_METRICS 为什么查不到预期计数器
- 128浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · 定时任务 · mysql 定时任务 Event Event Scheduler ON COMPLETION
- MySQL EVENT 怎样让一次性定时任务执行后自动删除
- 345浏览 收藏
-
- 数据库 · MySQL | 2小时前 |
- MySQL EXPLAIN 怎样看懂 filesort 的来源
- 447浏览 收藏
-
- 数据库 · MySQL | 2天前 | 类型转换 · mysql 默认值 ON EMPTY ON ERROR JSON路径 JSON_VALUE
- MySQL JSON_VALUE 怎样给缺失路径提供默认值
- 420浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- MySQL LOAD DATA 怎样把空字段导入为 NULL
- 286浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 931次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 937次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1038次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1015次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 844次使用
-
- MySQL 明明加了索引,为什么查询还是很慢?先查这 6 个点
- 2026-06-27 374浏览
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- golang xorm 自定义日志记录器之使用zap实现日志输出、切割日志(最新)
- 2023-02-24 432浏览
-
- Go语言常用的打log方式详解
- 2023-02-24 485浏览
-
- golang 基于 mysql 简单实现分布式读写锁
- 2023-01-07 384浏览

