mysql redolog binlog 之二阶段提交

文章目录

      • 一:什么是redolog和binglog?
      • 二:redolog和binlog可以相互替代或者只保留其一吗?
        • 1. 可以使用binlog替代redolog进行数据恢复吗?
        • 2. 可以只使用redolog而不使用binlog吗?
      • 三:为什么redolog和binlog要进行二阶段提交?
      • 四:二阶段提交步骤
      • 五、redolog和binlog二阶段提交与redolog和binlog的顺序提交是否真的有区别?
      • 六:恢复步骤?

一:什么是redolog和binglog?

redo log Binglog
日志类型 物理日志
物理日志即数据页中的真实二级制数据,恢复速度快
逻辑日志
即sql语句,因需要逐条执行,恢复速度慢
存储格式 innodb存储引擎数据的单位是页,redo log也是基于页进行存储,一个默认16K大小的页中存了很多512Byte的log block,log block的存储格式如下
[log block header 12Byte,log block body 492 Bytes,log block tailer 8 Bytes]
statement:SQL语句的形式
row:记录相关行的每一列的值(官方推荐)
用途 重做数据页 数据复制
所处层级 innodb存储引擎中 存储引擎的上层,因此不管用什么存储引擎,都可以开启binlog

二:redolog和binlog可以相互替代或者只保留其一吗?

1. 可以使用binlog替代redolog进行数据恢复吗?

不可以

innodb利用wal技术进行数据恢复,write ahead logging技术依赖于物理日志进行数据恢复,binlog不是物理日志是逻辑日志,因此无法使用

2. 可以只使用redolog而不使用binlog吗?

不可以

redolog是循环写,写到末尾要回到开头继续写,这样的日志无法保留历史记录,无法进行数据复制。

三:为什么redolog和binlog要进行二阶段提交?

首先区分一个概念,commit步骤是属于begin…commit语句中的一个步骤,且是最后一个步骤,两个commit是包含的关系。

如果redo log持久化并进行了提交,而binlog未持久化数据库就crash了,则从库从binlog拉取数据会少于主库,造成不一致。因此需要内部事务来保证两种日志的一致性。

四:二阶段提交步骤

mysql redolog binlog 之二阶段提交_第1张图片
prepare:redolog写入log buffer,并fsync持久化到磁盘,在redolog事务中记录2PC的XID,在redolog事务打上prepare标识
commit:binlog写入log buffer,并fsync持久化到磁盘,在binlog事务中记录2PC的XID,同时在redolog事务打上commit标识
其中,prepare和commit阶段所提到的“事务”,都是指内部XA事务,即2PC

五、redolog和binlog二阶段提交与redolog和binlog的顺序提交是否真的有区别?

如果redolog和binlog顺序提交,则具体步骤会如下:

  1. redolog刷入cache并fsync刷盘,并打上commit标识

  2. binlog刷入cache并fsync刷盘

类比begin…commit和begin…rollback,commit和rollback这两个操作是只能二选一,且一旦commit则不能再rollback。同样,redolog中的事务一旦打上commit标识,是无法回退的,否则有可能覆盖其他事务的更新(例如A事务对某一行进行了插入并打上commit标识,而B事务紧接着对该行进行了修改,最后A事务突然回滚B事务,则B事务的操作被强制覆盖,这是不妥的)。如果redolog进行了commit,而此时数据库crash导致binlog刷盘失败,redolog无法回滚,会造成redolog和binlog不一致。

但是通过事务可以同时提交redolog和binlog,两者落盘之后都会记录2PC事务的XID(redolog和binlog中事务落盘的标识),若中途数据库crash,通过XID关联两者并在恢复时决定commit和rollback与否,详细步骤见下一段“恢复步骤”。

六:恢复步骤?

redolog中的事务如果经历了二阶段提交中的prepare阶段,则会打上prepare标识,如果经历commit阶段,则会打上commit标识(此时redolog和binlog均已落盘)。

Step1. 按顺序扫描redolog,如果redolog中的事务既有prepare标识,又有commit标识,就直接提交(复制redolog disk中的数据页到磁盘数据页)

Step2 .如果redolog事务只有prepare标识,没有commit标识,则说明当前事务在commit阶段crash了,binlog中当前事务是否完整未可知,此时拿着redolog中当前事务的XID(redolog和binlog中事务落盘的标识),去查看binlog中是否存在此XID

​ a. 如果binlog中有当前事务的XID,则提交事务(复制redolog disk中的数据页到磁盘数据页)

​ b. 如果binlog中没有当前事务的XID,则回滚事务(使用undolog来删除redolog中的对应事务)

可以将mysql redolog和binlog二阶段提交和广义上的二阶段提交进行对比,广义上的二阶段提交,若某个参与者超时未收到协调者的ack通知,则会进行回滚,回滚逻辑需要开发者在各个参与者中进行记录。mysql二阶段提交是通过xid进行恢复。

参考:
http://blog.itpub.net/28218939/viewspace-1975809/
https://www.cnblogs.com/f-ck-need-u/p/9010872.html#auto_id_16
https://www.cnblogs.com/f-ck-need-u/p/9001061.html#auto_id_14
https://www.infoq.cn/article/M6g1yjZqK6HiTIl_9bex
https://www.cnblogs.com/wupeixuan/p/11734501.html
https://segmentfault.com/a/1190000014810628
https://www.cnblogs.com/stevenczp/p/6265686.html
https://www.cnblogs.com/clouddbdever/p/5627409.html
https://juejin.im/post/5e5c6620f265da5741120978#heading-4

你可能感兴趣的:(数据库)