引言
一提到mysql的二进制日志文件binlog, 一般会想到数据库备份,主从同步。没错这个日志是在server层产生,也就是说只要数据有变化,都会往该日志中记录,是一个通用日志。
binlog
我们要明确binlog日志是在事务提交完成之后,才会写入,这里与redo.log有着很明显的差异。 binlog日志的格式有三种情况,第一种就是stament原文写入,就是将原来的sql重新记录一份,但这样会有问题,比如说sql中引用了函数,函数的值与调用的时间会导致结果是不一样的,这种情况会导致备份的数据产生差异。第二种是row,是包含sql操作与数据,分开记录。这种格式恰恰解决了第一种的问题。 但是这样就会导致日志比较多。 所以出现了第三种格式, mixed,结合了第一种和第二种。通过上述,我们看到设计者想了很多巧妙的方法来解决各种各样的问题,不由的对设计者的聪明才智感到敬佩。
写入机制
事务在执行过程中, 这个时候还不是直接写到磁盘当中,而是会先写入到binlog cache中,可以理解为内存中的一块缓冲区, 当事务提交完成后,再将binlog cache 写到binlog当中。 这里和redo.log刷盘一样,也存在不同的刷盘时机。 binlog的刷盘存在三种情况, 0:系统自行判断;1. 每次事务提交完成后, 自动进行刷盘;2: 每次提交N个事务后, 再进行刷盘。 这里要考虑的是数据一致性与性能综合考虑,结合不同的场景选择合适的刷盘时机。
二阶段提交
binlog与redolog都是为了保证数据一致性而设计的,以事务为触发点,但是侧重点不同。 如果两份日志的逻辑不一致,会出现什么情况呢?比如redolog写入成功,binlog写入发生异常。就会导致原库因通过redolog数据得到恢复,而binlog中由于没有,导致从库与原库的数据不一样。所以mysql提出了两阶段提交方式, 事务进行中,redolog进入prepare阶段,待事务提交完成后,写入binlog日志记录数据同时redolog变成commit阶段。倘若binlog阶段写入异常,这个时候会进行事务回滚。如果redo log还处于prepare阶段,这个时候需要去判断binlog的日志是否完整,如果完整,则继续提交事务并恢复数据。
使用场景
- 主从复制
Master节点开启binlog,然后binlog日志被发往slave节点, slave节点执行binlog从而达到主从数据一致 - 数据恢复
通过mysqlbinlog工具恢复数据