两阶段提交
在两阶段提交的不同时刻,MySQL异常重启会出现什么现象?
- 当在时刻A的地方,也就是写入了redo log处于prepare阶段,写binlog之前,发生了crash,此时由于还没有写binlog,redo log也还没有commit,因此,崩溃恢复的时候这个事务会回滚。这个时候binlog还没有写,也不会同步到备份库中。
当在时刻B,也就是写完binlog之后系统发生了crash,崩溃恢复时分两种情况
statement格式的binlog,最后会有COMMIT;
- row格式的binlog,最后会有XID event
MySQL5.6.2版本之后,引入了binlog-checksum参数,用来验证binlog内容的正确性。对于binlog日志由于磁盘的原因,可能会在存储日志的过程中出错,MySQL可以通过checksum的结果来发现。所以MySQL还是有办法验证事务binlog的完整性的。
binlog和redo log是怎么关联起来的?
binlog和redo log有一个共同的字段XID。崩溃恢复的时候,会按顺序扫描redo log
- 如果碰到既有prepare,又有commit的redo log就直接提交
- 如果碰到只有prepare的redo log,就拿着XID去binlog找对应的事务
为何还需要两阶段提交?
两阶段提交是经典的分布式问题,并不是MySQL独有的。
双重保障。为什么binlog不支持崩溃恢复?
binlog没有能力恢复数据页,一个事务的binlog如果回放,就是重做这个事务,一个事务更新的可能不止一个page。
比如一个事务更新了page ABC
然后崩溃回复了,B坏了,AC没问题,而且AC还落盘了。
这样如果重做事务,B好了,AC又坏了。能不能只用redo log,不用binlog?
binlog有着redo log无法替代的功能,如主从复制,就是通过binlog实现的。数据最终写入磁盘,是从redo log更新的吗?
不是,因为redo log的大小是固定的,并没有记录完整的数据页的数据,所以它没有能力去更新磁盘数据。
