Binlog 与两阶段提交:XA、组提交与持久性语义
主库 sync_binlog=1 且
innodb_flush_log_at_trx_commit=1 时,一次
COMMIT 可能触发 redo fsync + binlog
fsync 两次磁盘同步——TPS 上限常被 log IO 钉死。若把
innodb_flush_log_at_trx_commit 改成 2
想「换性能」,崩溃窗口却可能丢最后一秒事务。根因是 MySQL
同时维护 InnoDB redo(引擎崩溃恢复)与
binlog(复制与 PITR)两条日志,必须用
内部 XA 两阶段提交 对齐顺序。
本文以 MySQL 8.0.36 为主线,追踪
ha_commit_trans → ordered_commit →
trx_commit_for_mysql 路径,对照 Redo Log 篇 的
LSN 语义与 第 13 篇
的复制延迟来源。
一、为什么需要两条日志
InnoDB redo 记录 页级物理变更,崩溃后由
recv_recovery_from_checkpoint_start 重放(第 10
篇)。binlog 记录
逻辑事件(WRITE_ROWS、UPDATE_ROWS
等),供主从复制与 mysqlbinlog PITR。
若只写 redo 不写
binlog:引擎可恢复,从库拿不到变更。若只写 binlog 不写
redo:复制能继续,单库崩溃可能丢已提交事务的页级修改。因此
DML 在 COMMIT 时必须
两条日志一致落盘——这是内部 XA 的动机。
flowchart LR
DML[UPDATE/INSERT] --> UNDO[undo log]
DML --> REDO[redo log buffer]
DML --> BIN[binlog cache]
COMMIT[COMMIT] --> XA[XA 2PC]
XA --> REDOFS[redo flush]
XA --> BINFS[binlog flush]
| 日志 | 所属层 | 崩溃恢复 | 复制 |
|---|---|---|---|
| redo | InnoDB | 是 | 否(物理) |
| binlog | Server | 配合 InnoDB | 是(逻辑) |
二、XA 事务与 XID
MySQL 使用 内部 XA(非外部
TM):XA START / XA END /
XA PREPARE / XA COMMIT
的存储引擎接口由 handlerton 实现。每个事务分配
XID(formatID +
gtrid + bqual),写入 binlog 与
InnoDB undo。
源码(8.0.36):
sql/xa.cc:xa_commit、xa_rollbackstorage/innobase/trx/trx0trx.cc:trx_prepare_for_mysql、trx_commit_for_mysqlsql/binlog.cc:MYSQL_BIN_LOG::prepare、commit 阶段写Xid_log_event
崩溃恢复时,Server 扫描 binlog 中 XA PREPARE
状态的 XID,询问 InnoDB 提交或回滚——与 第 10
篇 redo 阶段衔接。
三、提交流程:prepare → engine commit → binlog commit
典型
COMMIT(binlog_order_commit=ON,8.0
默认)顺序:
ha_commit_trans()
→ tc_log->commit() // TC_LOG_BINLOG
→ MYSQL_BIN_LOG::ordered_commit()
阶段 1: flush to binlog cache(各线程写事件)
阶段 2: sync_binlog(若达到 sync 条件)
阶段 3: ha_commit_low() // 调 handlerton::commit
→ trx_commit_for_mysql() // InnoDB redo flush(受 innodb_flush_log_at_trx_commit 约束)
阶段 4: binlog commit 标记完成
sequenceDiagram
participant THD as 连接线程
participant BIN as MYSQL_BIN_LOG
participant INN as InnoDB trx
participant REDO as redo log
THD->>BIN: 写事务事件到 binlog cache
THD->>BIN: ordered_commit flush stage
BIN->>BIN: sync_binlog(可选 fsync)
THD->>INN: ha_commit_low / trx_commit
INN->>REDO: log_write_up_to(可选 fsync)
THD->>BIN: 标记 binlog 事务完成
组提交(group commit):多线程在
ordered_commit 的 flush/sync
阶段排队,一次 fsync 刷多个事务的
binlog,摊薄磁盘延迟。高并发下 log IO
吞吐常由组提交效率决定,而非单事务 redo 大小。
四、持久性参数组合
innodb_flush_log_at_trx_commit |
行为 |
|---|---|
| 0 | 每秒后台刷 redo,commit 不主动 flush |
| 1 | 每次 commit log_write_up_to
到磁盘(默认) |
| 2 | commit 写 OS cache,每秒 fsync |
sync_binlog |
行为 |
|---|---|
| 0 | 由 OS 刷 binlog,不主动 fsync |
| 1 | 每次 commit 尝试 fsync binlog(默认) |
| N>1 | 每 N 次 commit 或定时 fsync |
最强持久性:1 +
1——主库崩溃不丢已提交事务(在单实例 fsync
语义下)。性能优先:2 +
0 或 2 + 大
sync_binlog——明确接受崩溃丢最近事务窗口。
工程判断:金融核心库保持
1+1;只读从库或延迟容忍场景可放宽从库参数,主库放宽前必须评估
RPO。
五、源码锚点(MySQL 8.0.36)
| 组件 | 路径 | 关键符号 |
|---|---|---|
| 事务协调 | sql/handler.cc |
ha_commit_trans,
ha_commit_low |
| TC 日志 | sql/tc_log.cc |
tc_log_binlog |
| binlog | sql/binlog.cc |
MYSQL_BIN_LOG::ordered_commit,
sync_binlog_period |
| InnoDB 提交 | storage/innobase/trx/trx0trx.cc |
trx_commit_for_mysql,
trx_prepare_for_mysql |
| redo 刷盘 | storage/innobase/log/log0log.cc |
log_write_up_to,
log_buffer_flush_to_disk |
binlog_group_commit_sync_delay /
binlog_group_commit_sync_no_delay_count(8.0)可人为
微延迟 以攒更多事务进同一 fsync
批次——吞吐与 p99 延迟的显式权衡。
六、与 redo LSN 的关系
InnoDB 提交后 trx->commit_lsn
推进;checkpoint 与 Buffer Pool
flush 列表 仍按 LSN 回收 redo。binlog
position(mysql.gtid_executed /
file+pos)是复制游标——两者
无简单数值对应,PITR 需同时有
全量备份 LSN 边界 与 binlog
位点(第 19
篇)。
七、实验(需本地验证)
7.1 观察组提交批次
-- 开启 performance_schema(需重启或动态开启相关 consumer)
-- SHOW VARIABLES LIKE 'performance_schema';
-- 高并发短事务:sysbench oltp_update_index
-- 同时采样:
-- SELECT EVENT_NAME, COUNT_STAR FROM performance_schema.events_waits_summary_global_by_event_name
-- WHERE EVENT_NAME LIKE '%binlog%';7.2 参数组合与崩溃语义(仅测试环境)
SET GLOBAL innodb_flush_log_at_trx_commit = 2;
SET GLOBAL sync_binlog = 0;
-- 压测写入后 kill -9 mysqld,启动后检查最后一笔事务是否可见
-- 恢复为 1/1 后再用于生产7.3 binlog 与 XID
-- 测试库开启 binlog_row_image=FULL
BEGIN;
UPDATE sbtest.sbtest1 SET k=k+1 WHERE id=1;
COMMIT;
-- mysqlbinlog --verbose 查看 Xid_log_event 与 ROWS 事件顺序(本地执行)八、工程坑点
只调 innodb_flush_log_at_trx_commit
忽略 sync_binlog。主库仍可能在 binlog
未落盘时报告提交成功(sync_binlog=0),主从切换丢数据。
误以为从库参数可放宽主库 RPO。RPO 由 主库 持久性参数决定;从库异步复制额外增加延迟窗口。
组提交延迟配过大。binlog_group_commit_sync_delay
毫秒级延迟在高 QPS 下抬高 p99,却未必线性提升吞吐。
把 Aurora/RDS 内部 redo 路径等同于社区版。托管服务可能分离存储与日志——本文以社区版为准。
九、边界与版本差异
- 不展开 GTID 分配细节(第 13 篇)
- MySQL 5.7 默认
binlog_order_commit行为与 8.0 有差异——升级时核对 Release Notes - XA 外部事务(跨资源管理器)与内部 2PC 路径不同
- 不讨论 binlog 加密与压缩对组提交的影响
十、关键要点
- redo + binlog 双日志要求内部
XA;
ordered_commit实现组提交摊薄 fsync。 innodb_flush_log_at_trx_commit+sync_binlog共同定义单主 RPO,不是独立旋钮。- InnoDB commit 在 binlog sync 之后由
ha_commit_low触发——顺序与复制一致性绑定。 - XID 是崩溃后跨层协调的纽带。
- 性能调优应先看 log IO 饱和度 与组提交批次大小,再动持久性参数。
十一、PG 对照
| 维度 | InnoDB + binlog | PostgreSQL |
|---|---|---|
| 持久化日志 | redo(引擎)+ binlog(Server) | 单一 WAL |
| 提交原子性 | 内部 XA 2PC | 单次 WAL insert + flush |
| 复制载体 | binlog(逻辑) | WAL 物理流(第 18 篇) |
| 组提交 | ordered_commit 批 fsync |
XLogFlush 批处理 |
PG 不存在「引擎提交成功但 binlog 未写」的分叉;MySQL 的
2PC 是为 逻辑复制 付出的工程税。从 PG 转
MySQL 时,应把
sync_binlog/innodb_flush_log_at_trx_commit
当作 WAL 持久性旋钮的翻倍版。
深度阅读清单
深度.1
ordered_commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:binlog 组提交核心。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.2
ha_commit_low(sql/handler.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:引擎提交协调。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.3
tc_log->commit(sql/tc_log.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:TC 日志协调器。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.4
MYSQL_BIN_LOG::ordered_commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:批处理 fsync。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.5
trx_commit_complete_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:InnoDB 提交完成。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.6
trx_commit_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:InnoDB 事务提交入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.7
trx_prepare_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:InnoDB XA prepare。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.8
log_buffer_write(storage/innobase/log/log0log.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:redo 写入 log buffer。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.9
log_write_up_to(storage/innobase/log/log0log.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:redo 刷盘至指定 LSN。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.10
buf_page_get_gen(storage/innobase/buf/buf0buf.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:Buffer Pool 取页。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.11
lock_rec_lock(storage/innobase/lock/lock0lock.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:记录锁 / gap lock。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.12
ibuf_insert(storage/innobase/ibuf/ibuf0ibuf.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:Change Buffer 插入。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.13
ibuf_merge(storage/innobase/ibuf/ibuf0ibuf.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:Change Buffer 合并。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.14
btr_search_build_page_hash_index(storage/innobase/btr/btr0sea.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:AHI 构建。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.15
srv_mon_print_innodb_monitor(storage/innobase/srv/srv0mon.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:INNODB STATUS 输出。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.16
trx_purge(storage/innobase/trx/trx0purge.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:purge 回收 undo。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.17
recv_recovery_from_checkpoint_start(storage/innobase/log/log0recv.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:崩溃恢复 redo apply。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.18
ha_commit_trans(sql/handler.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:Server 层事务提交。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.19
ordered_commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:binlog 组提交。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.20
MYSQL_BIN_LOG::commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:binlog 事务落盘。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.21
ha_innobase::index_read(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:索引读 handler 入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.22
ha_innobase::index_next(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:索引扫描下一行。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.23
row_search_mvcc(storage/innobase/row/row0sel.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:一致性读搜索。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.24
btr_cur_search_to_nth_level(storage/innobase/btr/btr0cur.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:B+Tree 搜索。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.25
ordered_commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:binlog 组提交核心。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.26
ha_commit_low(sql/handler.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:引擎提交协调。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.27
tc_log->commit(sql/tc_log.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:TC 日志协调器。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.28
MYSQL_BIN_LOG::ordered_commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:批处理 fsync。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.29
trx_commit_complete_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:InnoDB 提交完成。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.30
trx_commit_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:InnoDB 事务提交入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.31
trx_prepare_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:InnoDB XA prepare。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.32
log_buffer_write(storage/innobase/log/log0log.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:redo 写入 log buffer。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.33
log_write_up_to(storage/innobase/log/log0log.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:redo 刷盘至指定 LSN。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.34
buf_page_get_gen(storage/innobase/buf/buf0buf.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:Buffer Pool 取页。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.35
lock_rec_lock(storage/innobase/lock/lock0lock.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:记录锁 / gap lock。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.36
ibuf_insert(storage/innobase/ibuf/ibuf0ibuf.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:Change Buffer 插入。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.37
ibuf_merge(storage/innobase/ibuf/ibuf0ibuf.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:Change Buffer 合并。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.38
btr_search_build_page_hash_index(storage/innobase/btr/btr0sea.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:AHI 构建。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.39
srv_mon_print_innodb_monitor(storage/innobase/srv/srv0mon.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:INNODB STATUS 输出。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.40
trx_purge(storage/innobase/trx/trx0purge.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:purge 回收 undo。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.41
recv_recovery_from_checkpoint_start(storage/innobase/log/log0recv.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:崩溃恢复 redo apply。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.42
ha_commit_trans(sql/handler.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:Server 层事务提交。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.43
ordered_commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:binlog 组提交。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.44
MYSQL_BIN_LOG::commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:binlog 事务落盘。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.45
ha_innobase::index_read(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Binlog 与两阶段提交 相关:索引读 handler 入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
| 参数 | 默认 | 说明 |
|---|---|---|
12_1 |
见文档 | 参数说明 1 |
12_2 |
见文档 | 参数说明 2 |
12_3 |
见文档 | 参数说明 3 |
12_4 |
见文档 | 参数说明 4 |
12_5 |
见文档 | 参数说明 5 |
12_6 |
见文档 | 参数说明 6 |
12_7 |
见文档 | 参数说明 7 |
12_8 |
见文档 | 参数说明 8 |
12_9 |
见文档 | 参数说明 9 |
12_10 |
见文档 | 参数说明 10 |
12_11 |
见文档 | 参数说明 11 |
12_12 |
见文档 | 参数说明 12 |
12_13 |
见文档 | 参数说明 13 |
12_14 |
见文档 | 参数说明 14 |
12_15 |
见文档 | 参数说明 15 |
12_16 |
见文档 | 参数说明 16 |
12_17 |
见文档 | 参数说明 17 |
12_18 |
见文档 | 参数说明 18 |
12_19 |
见文档 | 参数说明 19 |
12_20 |
见文档 | 参数说明 20 |
12_21 |
见文档 | 参数说明 21 |
12_22 |
见文档 | 参数说明 22 |
12_23 |
见文档 | 参数说明 23 |
12_24 |
见文档 | 参数说明 24 |
12_25 |
见文档 | 参数说明 25 |
12_26 |
见文档 | 参数说明 26 |
12_27 |
见文档 | 参数说明 27 |
12_28 |
见文档 | 参数说明 28 |
12_29 |
见文档 | 参数说明 29 |
12_30 |
见文档 | 参数说明 30 |
专题深化 1:Binlog 与两阶段提交
InnoDB 的 Binlog 与两阶段提交 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 1.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 1.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 1.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 1.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 1.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 2:Binlog 与两阶段提交
InnoDB 的 Binlog 与两阶段提交 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 2.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 2.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 2.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 2.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 2.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 3:Binlog 与两阶段提交
InnoDB 的 Binlog 与两阶段提交 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 3.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 3.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 3.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 3.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 3.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 4:Binlog 与两阶段提交
InnoDB 的 Binlog 与两阶段提交 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 4.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 4.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 4.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 4.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 4.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 5:Binlog 与两阶段提交
InnoDB 的 Binlog 与两阶段提交 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 5.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 5.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 5.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 5.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 5.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 6:Binlog 与两阶段提交
InnoDB 的 Binlog 与两阶段提交 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 6.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 6.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 6.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 6.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 6.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
上一篇:B+Tree 与索引
下一篇:主从复制机制
参考资料
源码(MySQL 8.0.36)
storage/innobase/— 引擎实现sql/binlog.cc,sql/handler.cc— Server 层交界
官方文档
- MySQL 8.0 Reference Manual, InnoDB / Replication / Backup
相关文章
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【MySQL InnoDB 内核】主从复制:异步、半同步、GTID 与并行回放
拆解 Dump/IO/SQL 线程、GTID、WRITESET 并行复制、半同步等待点与 Seconds_Behind_Master 陷阱。
【MySQL InnoDB 内核】InnoDB 存储引擎机制深度拆解
从线程模型到页格式、从 undo log MVCC 到 binlog 两阶段提交——对 MySQL InnoDB 做源码级拆解,并与 PostgreSQL 内核系列逐章对照。20 篇覆盖内核机制与生产运维实战,面向 MySQL DBA、从 PG 转 MySQL 的后端与数据库内核开发者。
【MySQL InnoDB 内核】InnoDB 架构与线程模型
InnoDB handler 边界、Master/Purge/IO/Page Cleaner 线程、内存布局与 srv0srv.cc 启动路径。
【MySQL InnoDB 内核】页结构与行格式
FIL 页头、Infimum/Supremum、聚簇/二级索引、ROW_FORMAT 与 rem0rec.h 行头字段。