一个事务的执行方式(一般存在显式开启和隐式开启,在未申明的情况下一般是隐式事务):redo log存在两阶段提交,prepare和commit.当写完redo log 时,开始写 bin log ,当bin log写完,会在这次事务的最后加上commit(xid),标志这次事务是完整的,此时再在redo log的最后加上commit 标志此次事务完整,再将内存中的数据刷到磁盘。
基于上面的逻辑,判断事务回滚。
当mysql异常重启,判断顺序,首先是判断redo log是否commit,再去判断bin log。redo log已经有commit标记,那么事务一定提交。
(1) A时刻,当redo log处于prepare阶段,如果此时bin log未写完整,也就是还未进行commit,此时事务会进行回退,不会存储到数据库。
(2) A时刻,当redo log处于prepare阶段,如果此时bin log已经commit,则会提及事务,将数据存储到数据库
(3) B时刻,基于上面的理论,当处于B时刻,事务一定会被提交。
为什么mysql要设计成redo log 处于parper阶段时,bin log commit 就需要提交事务。
因为当数据库重启时,从库会基于bin log进行数据同步和恢复,如果主库binlog已经commit标记,而事务未提交,而从库根据Binlog同步后提交了,那么数据就存在不一致,说到底也就是保证数据的一致性。