一、比较

1、存储内容

redolog 重做日志,是innodb独有的文件,存储事务日志。记录的是具体修改了哪些页上做了哪些修改,是从修改实际存储介质上分析,所以是物理日志
binlog 归档日志,是mysql通用文件,在mysql-server里产生,可以用在任何支持的存储引擎上。记录的是dml的sql的原始逻辑,对哪些记录做了哪些修改,是从sql语句逻辑上分析,所以是逻辑日志。按指定行格式来记录,支持statement、row和mixed三种方式

  • statement - 是记录sql语句,记录量小,但不能记录调用到的函数影响的结果等
  • row - 会记录所有修改的行记录,所以日志规模庞大,修改多条就会记录多条等
  • mixed - 兼容上面两种方式,一般语句修改以statement方式记录,修改表、涉及函数无法完成主从复制等以row格式记录

2、文件形式

redolog 是有限空间,一般以文件组形式存在,写完一组文件后会从头开始擦除重写,以checkpoint标识要擦除的位置,擦除前会先把记录刷新到磁盘,write pos和checkpoint之间的空间就是可写的。
引用丁奇大佬
image.png
binlog 是追加写入,写完一个继续写下一个。

3、 用途

redolog 用于innoddb存储引擎的崩溃恢复,因为redolog保证了crashlog。redolog记录的是发生了的页修改信息,如果写入日志后mysql异常崩溃了,重启后,innodb会读取redolog文件修复未完成的事务提交
binlog 用于主从复制或重放恢复数据,当要备份或做加slave库时,从binlog读取并同步到slave库上
redolog修改的物理页的操作,比如插入1和2可能是主键1和辅助索引2由于b+tree的原因会各自生成一条记录,要恢复的是这个页面的操作;而binglog是逻辑值,即只管最终结果的恢复。

二、两阶段提交

继续引用丁奇大佬
image.png

1、 第一阶段:prepare

修改内存,先记录redolog,进入prepare阶段,并不提交事务,然后记录binlog,成功后

2、第二阶段:commit

提交事务

3、分析:why始终比what重要

首先要明白两阶段提交是指两阶段都完成才算是真正的完成事务,也就是说上面说的写入redolog和binlog是一个整体,谁失败了都说明第一阶段失败了,整个事务就是失败了。
分析两阶段提交就是分析第一阶段的成败关键(后面讲原因?)

还是继续用丁奇大佬的反正法,即如果不是两阶段提交,那也就是说第一阶段只完成了redolog或binlog的一种。假设id=1的记录c=1,然后执行一条语句:

  1. update t set c = 2 where id = 1

并且内存一更新完成,此时如果:

a. 先完成了redolog,binlog还未写入,mysql异常重启了,此时innodb可根据redolog恢复主库c的值为2,但由于binlog写入失败,记录的还是c=1,所以备份中存储在的还是c=1,当从库从备份拿到数据要恢复c时,发现与主库的值不同

b. 先完成了binlog,redolog还未写入,mysql异常重启了,此时innodb未记录c=2,所以主库的c=1,但由于binlog记录了c=2,当从库从备份拿到数据要恢复c时,发现与主库的值不同

综合上面两点,有一个没完成,第一阶段就是失败的,而当第一阶段完成,事务还没提交,mysql异常重启了,此时因为日志是全的,恢复后主库与从库的值都是最新的,所以第二阶段不影响两阶段提交的结果,这就是为什么只需要分析第一阶段的关键因素了。

两种日志都记录了事务的提交状态,两阶段提交保证了两个状态逻辑上的一致。

**

三、为什么这么设计

1、为什么要设计WAL(write-ahead Logging)

访问磁盘io慢时,为了支持高并发访问量,先顺序写入redolog,并更新完内存,然后在线程空闲时刷新到磁盘。这是mysql为了解决当前访问io慢的一种技术。

2、为什么不能用binlog做崩溃恢复

历史原因:当初设计binlog只是为了备份,不是为了崩溃恢复,所以不保证crash-safe
操作原因:binlog是可以关掉的,set sql_log_bin=0 可以关掉本线程的binlog

3、为什么不能用redolog做备份

a. redolog目前还只是innodb独有,其他引擎不支持
b. redolog是有限空间,会擦除重写,而binlog是一直追加