两阶段提交
两阶段提交的不同时刻,mysql异常重启会出现什么现象?
写入内存->写入redo log处于prepare阶段-(A时刻)>写binlog-(B时刻)>提交事务,处于commit状态
- A时刻,写binlog之前发生崩溃,redo log未提交,这时候binlog还没写,所以崩溃回复的时候不会存在
- B时刻,redo log还没commit,mysql的处理方式
- 如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交;
- 如果 redo log 里面的事务只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整:
a. 如果是,则提交事务;
b. 否则,回滚事务
崩溃恢复时,扫描redo log 如果prepare+commit直接提交,如果是只有prepare的,就去找binlog.
binlog完整判断
一个事务的 binlog 是有完整格式的:
statement 格式的 binlog,最后会有 COMMIT;
row 格式的 binlog,最后会有一个 XID event。
另外,在 MySQL 5.6.2 版本以后,还引入了 binlog-checksum 参数,用来验证 binlog
内容的正确性。对于 binlog 日志由于磁盘原因,可能会在日志中间出错的情况,MySQL
可以通过校验 checksum 的结果来发现。所以,MySQL 还是有办法验证事务 binlog 的
完整性的。
binlog和redo log关联
共同字段XID关联两种日志.
两阶段提交
两阶段提交是经典的分布式系统问题,并不是mysql独有的.
binlog
binlog并没有记录数据页的更新细节,所以无法替代redo log.
redo log事实上就是binlog优化的结果.
redo log
循环写,无法代替binlog归档的功能.