MySQL两段式提交
两段式提交是MySQL数据持久化的保证。
两种日志
binlog和redolog
binlog记录了数据库表结构和表数据变更,主要有两个作用:复制和恢复数据
redo log 是 Innodb 引擎独有的日志模块,它只记录有关 Innodb 引擎的事务日志,记录内容为 对数据页的物理操作
binlog | redolog | |
---|---|---|
适用对象不同 | mysql server 层 | Innodb 存储引擎层 |
写入方式不同适用对象不同 | 追加写,一个文件满了写新文件mysql server 层 | 循环写固定文件Innodb 存储引擎层 |
写入方式不同 | 逻辑日志,一个事务具体操作内容 | 物理日志,页的修改情况 |
写入磁盘时间不同 | 提交事务前一次写入 | 在事务进行中有后台线程不断同步 |
用途不同 | 主从复制、数据备份 | 数据恢复 |
两段式提交
两种日志虽然都保证持久化,但是侧重点不同。
1、redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力。
2、binlog(归档日志)保证了MySQL集群架构的数据一致性,主从节点的同步都是通过binlog保证的。
如果单独提交
先写 redo log 后写 binlog,也就是事务可能还没有提交,系统崩溃了,虽然可以通过redo log恢复,但是binlog还没有这条数据,就会造成主从不一致 先写 binlog 后写 redo log,这个过程说明事务已经提交了,系统崩溃了,虽然binlog里面有数据,但是redo log里面没有,也会发生主从不一致,并且redo log因为不全,即使重新恢复的时候也不是最新的数据
两段式提交
就是将redolog的提交拆为两各阶段,prepare阶段和commit阶段,在中间插入binlog提交。
发生异常
1、在prepare阶段写入redolog的时候发生异常,那不管redolog有没有写完,都会回滚,因为binlog没有写入,会导致日志不一样,主从数据不一致。
2、在commit阶段写入binlog的时候发生异常
如果在写完之前,那也会回滚,毕竟没写完和没写一样,会导致日志不一样,主从数据不一样。
如果在写完之后,那就不会回滚了,两种日志都写完了,能保证数据一致了。
3、在commit阶段提交redolog的时候发生异常,前面写完binlog就不会回滚了,那这里也不会回滚,能保证数据一致性。