暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL两阶段提交

原创 谭磊Terry 恩墨学院 2022-06-28
2757

两阶段提交的流程


MySQL想要准备事务的时候会先写redolog、binlog分成两个阶段。

两阶段提交的第一阶段 (prepare阶段):写redo-log 并将其标记为prepare状态。

紧接着写binlog

两阶段提交的第二阶段(commit阶段):写 redo-log并将其标记为commit状态。

 

两阶段写日志用意

binlog默认都是不开启的状态!

也就是说,如果你根本不需要binlog带给你的特性(比如数据备份恢复、搭建MySQL主从集群),那你根本就用不着让MySQL写binlog,也用不着什么两阶段提交。

只用一个redolog就够了。无论你的数据库如何crash,redolog中记录的内容总能让你MySQL内存中的数据恢复成crash之前的状态。

所以说,两阶段提交的主要用意是:为了保证redolog和binlog数据的安全一致性。只有在这两个日志文件逻辑上高度一致了。你才能放心的使用redolog帮你将数据库中的状态恢复成crash之前的状态,使用binlog实现数据备份、恢复、以及主从复制。而两阶段提交的机制可以保证这两个日志文件的逻辑是高度一致的。没有错误、没有冲突。

总的来说,不论mysql什么时刻crash,最终是commit还是rollback完全取决于MySQL能不能判断出binlog和redolog在逻辑上是否达成了一致。只要逻辑上达成了一致就可以commit,否则只能rollback。

 

如何判断binlog和redolog是否达成了一致

当MySQL写完redo log并将它标记为prepare状态时,并且会在redo log中记录一个XID,它全局唯一的标识着这个事务。而当你设置sync_binlog=1时,做完了上面第一阶段写redo log后,mysql就会对应binlog并且会直接将其刷新到磁盘中。

下图就是磁盘上的row格式的binlog记录。binlog结束的位置上也有一个XID。
只要这个XID和redo log中记录的XID是一致的,MySQL就会认为binlog和redo log逻辑上一致。就上面的场景来说就会commit,而如果仅仅是redo log中记录了XID,binlog中没有,MySQL就会RollBack

对于处于PREPARE状态的事务,存储引擎既可以提交,也可以回滚,这取决于目前该事务对应的binlog是否已经写入硬盘。这时就会读取最后一个binlog日志文件,从日志文件中找一下有没有该PREPARE事务对应的xid记录,如果有的话,就将该事务提交,否则就回滚好了。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论