当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL redo log 与 binlog 怎样判断提交顺序

MySQL redo log 与 binlog 怎样判断提交顺序

来源:17golang原创 2026-11-07 20:59:53 0浏览 收藏

如果把 redo log 和 binlog 简单理解成“谁先写谁就先提交”,很容易在崩溃恢复或主从延迟排查中得到错误结论。更准确的判断方式是:redo log 主要服务于 InnoDB 数据页的崩溃恢复,binlog 主要服务于事务复制和时间点恢复;两者会通过两阶段提交协同,但不是一份可以直接按文件偏移互相排序的日志。

在默认的 binlog_order_commits=ON 下,MySQL 会让事务按照写入 binlog 的顺序向存储引擎发出提交指令。因此,通常可以把 binlog 中事务组的先后看作提交顺序;但 redo log 的 LSN 只能说明 redo 记录在 InnoDB 日志流中的位置,不能单独证明事务已经对外提交。

MySQL 事务从 prepare 到 binlog 写入和提交的静态阶段关系图
图1:MySQL redo log、binlog 与提交阶段的静态结构说明图,不是运行截图或执行证据。

先把 redo log 和 binlog 放回各自职责

redo log 记录的是 InnoDB 对数据页做修改时产生的恢复信息,核心位置标识是不断增长的 LSN。实例异常退出后,InnoDB 依据 redo log 重放尚未完整落盘的数据页修改。它回答的是“数据页修改如何恢复”,而不是“复制线程应该按什么顺序执行事务”。

binlog 记录的是服务器层面的事务变更,供复制和时间点恢复使用。对事务表而言,事务中的变更通常在提交点附近作为一个事务组写入 binlog。它回答的是“哪些事务应该被复制或重放,以及它们在二进制日志中的排列是什么”。

所以,排查提交顺序时先记住两个边界:

  • redo log 的 LSN 是 InnoDB 日志位置,不是事务提交序号。
  • binlog 的文件偏移是二进制日志位置,不是 redo log 的 LSN。

一次提交大致经过哪些阶段

对于只涉及 InnoDB 的普通事务,可以用下面的抽象链路理解双写日志:

  1. 事务修改数据页,并在 InnoDB 日志系统中产生 redo 记录。
  2. 存储引擎进入 prepare 状态,服务器确认参与事务的存储引擎已经准备提交。
  3. 服务器将事务内容写入 binlog,组提交时多个事务可能一起完成这一阶段。
  4. 根据 sync_binlog、innodb_flush_log_at_trx_commit 等持久化策略完成相应刷盘动作。
  5. 服务器向存储引擎发出 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 LSNInnoDB 日志记录在日志流中的位置不能单独证明事务已经 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 作为恢复进度或日志空间推进的指标;但不要据此推导两个事务之间的完整提交顺序。

MySQL 通过 binlog 事务顺序与 redo LSN 边界交叉定位的静态关系图
图2:binlog 事务顺序与 redo 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 顺序和副本执行顺序不一样?复制线程数、并行调度和副本提交顺序配置都可能造成差异。
  • 怎样先保证一致性再追求吞吐量?先保持默认提交顺序并记录配置,再用明确的压测结果评估并行提交。
版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL 不同表使用同名 CHECK 约束为什么报错MySQL 不同表使用同名 CHECK 约束为什么报错
上一篇
MySQL 不同表使用同名 CHECK 约束为什么报错
MySQL innodb_print_all_deadlocks 怎样把死锁写入错误日志
下一篇
MySQL innodb_print_all_deadlocks 怎样把死锁写入错误日志
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    931次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    937次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1038次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1015次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    844次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码