redo log与binlog的区别
redo log又称重做日志文件,用于记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。
binlog记录了对MySQL数据库执行更改的所有操作,但是不包括SELECT和SHOW这类操作,因为这类操作对数据本身并没有修改。然后,若操作本身并没有导致数据库发生变化,那么该操作也会写入二进制日志。

第一:redo log是在InnoDB存储引擎层产生,而binlog是MySQL数据库的上层产生的,并且二进制日志不仅仅针对INNODB存储引擎,MySQL数据库中的任何存储引擎对于数据库的更改都会产生二进制日志。
第二:两种日志记录的内容形式不同。MySQL的binlog是逻辑日志,其记录是对应的SQL语句。而innodb存储引擎层面的redolog日志是物理日志,保存了数据库中的值。
第三:两种日志记录写入磁盘的时间点不同,二进制日志只在事务提交完成后进行一次写入。而InnoDB 存储引擎的重做日志在事务进行中不断地被写入(不断地写入redo log buffer,不断地刷新),这表现为日志并不是随事务提交的顺序进行写入的
二进制日志仅在事务提交时记录,并且对于每一个事务,仅在事务提交时记录,并且对于每一个事务,仅包含对应事务的一个日志。而对于innodb存储引擎的重做日志,由于其记录是物理操作日志,因此每个事务对应多个日志条目,并且事务的重做日志写入是并发的,并非在事务提交时写入,其在文件中记录的顺序并非是事务开始的顺序。
第四:binlog不是循环使用,在写满或者重启之后,会生成新的binlog文件,redo log是循环使用。
第五:binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。

如何保证redolog文件和binary文件的一致性

假设一:先写redo log再写binlog
想象一下,如果数据库系统在写完一个事务的redo log时发生crash,而此时这个事务的binlog还没有持久化。在数据库恢复后,主库会根据redo log中去完成此事务的重做,主库中就有这个事务的数据。但是,由于此事务并没有产生binlog,即使主库恢复后,关于此事务的数据修改也不会同步到从库上,这样就产生了主从不一致的错误。
假设二:先写binlog再写redo log
想象一下,如果数据库系统在写完一个事务的binlog时发生crash,而此时这个事务的redo log还没有持久化,或者说此事务的redo log还没记录完(至少没有记录commit log)。在数据库恢复后,从库会根据主库中记录的binlog去回放此事务的数据修改。但是,由于此事务并没有产生完整提交的redo log,主库在恢复后会回滚该事务,这样也会产生主从不一致的错误。

在MySQL内部,在事务提交时利用两阶段提交(内部XA的两阶段提交)很好地解决了上面提到的binlog和redo log的一致性问题:
第一阶段: InnoDB Prepare阶段。此时SQL已经成功执行,并生成事务ID(xid)信息及redo和undo的内存日志。此阶段InnoDB会写事务的redo log,但要注意的是,此时redo log只是记录了事务的所有操作日志,并没有记录提交(commit)日志,因此事务此时的状态为Prepare。此阶段对binlog不会有任何操作。
第二阶段:commit 阶段,这个阶段又分成两个步骤。第一步写binlog(先调用write()将binlog内存日志数据写入文件系统缓存,再调用fsync()将binlog文件系统缓存日志数据永久写入磁盘);第二步完成事务的提交(commit),此时在redo log中记录此事务的提交日志(增加commit 标签)。 还要注意的是,在这个过程中是以第二阶段中binlog的写入与否作为事务是否成功提交的标志。第一步写binlog完成 ,第二步redo log的commit未提交未完成,也算完成。