登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
导读
排行榜
资讯
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
小组
VIP申请
VIP网盘
网盘
联系我们
发帖说明
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
【面试题】MySQL 事务的二阶段提交是什么? ...
【面试题】MySQL 事务的二阶段提交是什么?
[ 复制链接 ]
这帜
3 天前
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
MySQL 的二阶段提交(Two-Phase Commit,2PC)是
InnoDB 存储引擎内部用于保证 redo log 和 binlog 一致性的关键机制
,确保事务的持久性和崩溃恢复能力。
1. 为什么需要二阶段提交?
MySQL 的事务提交需要同时写入两种日志:
binlog
:MySQL Server 层的逻辑日志,用于主从复制和数据恢复
redo log
:InnoDB 存储引擎的物理日志,用于崩溃恢复
如果没有协调机制,可能出现:
先写 redo 后写 binlog
:崩溃时事务已提交(redo 写完),但 binlog 丢失,导致从库丢失该事务
先写 binlog 后写 redo
:崩溃时 binlog 已写,但事务未提交(redo 未写),导致主从不一致
二阶段提交就是为了解决这两种日志的
原子性写入
问题。
2. 二阶段提交的具体过程
第一阶段:准备阶段(Prepare)
-- 1. 将事务的 redo log 写入 log buffer
-- 2. 将 redo log 标记为 PREPARE 状态(但未提交)
-- 3. 刷盘 redo log 到磁盘(保证持久化)
-- 此时事务还没有真正提交
复制代码
第二阶段:提交阶段(Commit)
-- 4. 将事务的 binlog 写入 binlog cache
-- 5. 将 binlog 刷盘到磁盘
-- 6. 将 redo log 标记为 COMMIT 状态
-- 7. 将 redo log 刷盘(可选,因为有 group commit 优化)
-- 此时事务才真正提交完成
复制代码
完整流程图:
开始事务
↓
写入 redo log (PREPARE 状态)
↓
刷盘 redo log ←--- 确保崩溃恢复时能找到"准备中"的事务
↓
写入 binlog ←--- 如果崩溃,恢复时会检查
↓
刷盘 binlog ←--- 确保主从复制不丢数据
↓
写入 redo log (COMMIT 状态)
↓
事务提交完成
复制代码
3. 崩溃恢复时的处理逻辑
MySQL 重启后,通过比较 redo log 和 binlog 来决定事务状态:
场景分析:
redo log 有 prepare,binlog 完整
事务在第二阶段提交前崩溃
恢复时发现 binlog 已完整写入 →
提交事务
redo log 有 prepare,binlog 不完整/不存在
事务在第一阶段后、写 binlog 前崩溃
恢复时发现 binlog 不完整 →
回滚事务
redo log 有 commit
事务已完整提交 →
无需处理
恢复算法伪代码:
for each transaction in redo_log:
if redo.status == COMMIT:
# 事务已提交,无需操作
continue
elif redo.status == PREPARE:
if binlog_contains(transaction.xid):
# binlog 完整,提交事务
commit_transaction(transaction)
else:
# binlog 不完整,回滚事务
rollback_transaction(transaction)
复制代码
4. 组提交(Group Commit)优化
为了解决二阶段提交的刷盘性能问题(两次刷盘:redo prepare 刷盘 + binlog 刷盘),MySQL 引入了
组提交
:
传统二阶段提交的问题:
每次事务提交都需要两次刷盘(redo + binlog)
磁盘 IO 成为瓶颈
组提交的工作原理:
准备阶段组提交
:多个事务的 redo log prepare 一次性刷盘
binlog 组提交
:多个事务的 binlog 一次性刷盘
提交阶段组提交
:多个事务的 redo log commit 一次性刷盘
优化效果
:将 N 个事务的 2N 次刷盘减少到 3 次刷盘。
5. 相关参数配置
-- 控制 redo log 刷盘策略(默认 1,最安全)
innodb_flush_log_at_trx_commit = 1
-- 0: 每秒刷盘一次
-- 1: 每次提交都刷盘(保证不丢数据)
-- 2: 写入 OS 缓存,不保证刷盘
-- 控制 binlog 刷盘策略(默认 1,最安全)
sync_binlog = 1
-- 0: 依赖 OS 刷盘
-- 1: 每次提交都刷盘
-- N: 每 N 次提交刷盘一次
-- 开启 binlog(必须开启才能有二阶段提交)
log_bin = ON
-- 使用 InnoDB 存储引擎(支持事务)
default_storage_engine = InnoDB
复制代码
6. 实际应用中的注意事项
数据一致性保证
二阶段提交确保了
即使服务器崩溃,也不会出现数据不一致
主从复制中,从库的数据与主库崩溃前一致
性能影响
二阶段提交有性能开销(两次刷盘)
生产环境通常配合组提交和适当的刷盘策略平衡性能与安全性
监控指标
-- 查看 binlog 状态
SHOW MASTER STATUS;
-- 查看 redo log 信息
SHOW ENGINE INNODB STATUS\G
-- 监控事务提交延迟
SELECT * FROM information_schema.INNODB_METRICS
WHERE NAME LIKE '%trx%commit%';
复制代码
总结
MySQL 的二阶段提交是
数据库 ACID 特性中持久性(Durability)的核心实现机制
:
解决的核心问题
:保证 redo log 和 binlog 的原子性写入
关键价值
:确保崩溃恢复后数据一致,主从复制可靠
实际优化
:通过组提交减少 IO 次数,提升性能
应用场景
:所有使用 InnoDB 并开启 binlog 的 MySQL 实例
理解二阶段提交对于设计高可用数据库架构、优化数据库性能、处理数据一致性等问题至关重要。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
试题
MySQL
事务
二阶段
提交
相关帖子
MySQL 5.6 2000 万行高频读写表新增字段实战:从慢执行到无锁落地全解析
【面试题】MySQL 中 count(*)、count(1) 和 count(字段名) 有什么区别?
GIM 2.0 发布:真正让 AI 提交消息可定制、可控、可项目级优化
Redis 事务的“原子性”迷思:为什么我们最终选择了 Lua 脚本
MYSQL日志
浅析二叉树、B树、B+树和MySQL索引底层原理
Seata实现分布式事务:大白话全剖析(核心讲透AT模式)
JAVA面试题速记-redis知识点
7 道 AI 编程高频面试题!涵盖 Cursor、Claude Code、Skills
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
业界
MySQL 5.6 2000 万行高频读写表新增字段实战:从慢执行到无锁落地全解析
10
728
乐敬
2026-02-02
业界
【面试题】MySQL 中 count(*)、count(1) 和 count(字段名) 有什么区别?
9
1031
向梦桐
2026-02-02
业界
GIM 2.0 发布:真正让 AI 提交消息可定制、可控、可项目级优化
11
901
忆雏闲
2026-02-02
业界
Redis 事务的“原子性”迷思:为什么我们最终选择了 Lua 脚本
15
765
纣捎牟
2026-02-05
安全
MYSQL日志
9
831
栓汨渎
2026-02-05
业界
浅析二叉树、B树、B+树和MySQL索引底层原理
11
632
岳娅纯
2026-02-06
业界
Seata实现分布式事务:大白话全剖析(核心讲透AT模式)
12
871
赖珊
2026-02-06
业界
JAVA面试题速记-redis知识点
1
592
左优扬
2026-02-23
业界
7 道 AI 编程高频面试题!涵盖 Cursor、Claude Code、Skills
1
939
老僻贞
2026-02-25
回复
(1)
判涔
昨天 03:39
回复
使用道具
举报
照妖镜
程序园永久vip申请,500美金$,无限下载程序园所有程序/软件/数据/等
懂技术并乐意极积无私分享的人越来越少。珍惜
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
这帜
昨天 03:39
关注
0
粉丝关注
26
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
3934307807
991125
anyue1937
9994892
kk14977
6845359
4
xiangqian
638210
5
宋子
9890
6
韶又彤
9913
7
闰咄阅
9993
8
刎唇
9995
9
蓬森莉
9877
10
遗憩
10006
查看更多
今日好文热榜
155
docker安装zabbix7.4
909
Condition底层机制剖析:多线程等待与通知
488
Condition底层机制剖析:多线程等待与通知
597
[拆解LangChain执行引擎]支持自然语言查询
781
深入理解 Java Deque 的设计哲学
1
流量精灵
880
Kite:两种方式实现动态表名
315
Ubuntu Linux 上 固定P/E 核混合架构CPU频
484
【FAQ】HarmonyOS SDK 闭源开放能力 — Loc
22
见证数智力量,甄知科技再获客户感谢信
910
TikTok小店上架产品发布新流程怎么操作?超
774
Apache SeaTunnel实战:MongoDB到Doris数据
733
行情系统为什么越做越慢?
970
JAVA WEB学习13
692
【实战】用 AI 吃透 Git Commit:从代码修
4
【实战】用 AI 吃透 Git Commit:从代码修
264
MAF快速入门(17)用户智能体交互协议AG-UI
195
从零开始构建实时客服系统(.NET架构系列)
157
一款基于 .NET Avalonia 开源、功能强大、
513
使用语义化版本管理工程:告别版本混乱