好巧,大概的讲讲吧。
首先,redo的存在保证了事务的原子性。而redo和binlog之间的XA是MySQL Server 与InnoDB Engine 之间沟通的桥梁,最大程度的保证了数据的安全。(MyRocks似乎也准备做引擎与binlog的XA,防止异常crash的时候丢数据)
下面开始答题:
一、事务各个阶段,redo和binlog的操作
prepare: 引擎层Prepare(写redo)
commit:1、先将redo落盘(可以想想为什么redo要先落盘) 2、Server层commit(写binlog) 3、引擎层commit(在redo中标记事务已提交)
二、recover 对于事务的判断
InnoDB崩溃恢复的过程包括 1、发现表空间 2、redo 的应用 3、回滚未提交事务 4、Change Buffer merge 5、purge 掉不再需要做MVCC以及回滚操作的日志 。
对于未提交的事务,我们一定会回滚掉。这个是没有问题的,关键在于,commit操作有第一问中的三个步骤,万一在进行到一般crash,这个事务怎么判断和执行。
简单回答: Server层commit就算commit(以binlog为准)
具体情况:对于进行到“引擎层commit”的事务,说明它已经走完了全程。binlog里面也必然有记录,毋庸置疑,这个事务是提交了的
对于进行到“Server层commit”这一步的事务,redo中没有标记事务已提交,但是binlog中存在,引擎recover的时候会将它提交,并在redo中标记
对于redo中有记录,但是binlog中没有的事务,直接回滚。
过程是这样的:扫描最后一个binlog,记录所有的 xid
扫描引擎层中未提交的事务(redo中未标记commit的事务),看它的xid是否在binlog中,在就提交,不在就回滚。
小广告:招DBA~~~欢迎私戳~~~