重做日志文件(redo log)和二进制文件(bin log)
bin logrhino文件的历史要比redo log日志文件的历史久,因为bin log是server层的日志文件,而server层是所有存储引擎共享的,其记录的是逻辑日志,简单的说就是具体的sql,但不是所有的sql都会记录,而是所有的数据库表结构和表数据变更,而redo log是innodb才有的,是存储引擎层的日志,记录的是物理日志,即数据的变化。
为什么bin log无法保证crach-safe?
bin log记录的是逻辑日志,也就是具体的操作,为什么无法保证呢?因为记录日志和执行操作是两个操作,不是原子操作。假如在期间什么时候出现了宕机都会出现数据不一致的问题。
redo log如何保证crach-safe?
同样是日志文件,为什么redo log就可以保证crach-safe呢?因为redo log记录的是物理日志,其记录的时间不是在事务执行之前或者之后,而是在事务执行中就记录了redo log,通过事务来控制原子性。并且,redo log可以保证之前还未提交的操作被记录了,数据可以恢复,所以保证了crach-safe。
那bin log的用途是什么?
bin log是用于主从数据同步的。
mysql的主从复制
mysql的slave模式中,为了减缓主数据库的访问压力,通过添加从数据库来减少对主数据库的访问,但是如何保证主从数据库数据的一致呢?
主库将更新操作保存在bin log 中,从库的IO线程从主库的bin log中读取到relay log中,sql thread 从relay log 中执行sql。
bin log 和redo log的一致性问题?
bin log用来实现主从复制,那么bin log也需要保证记录的数据的有效性,我们知道redo log中的数据是有效的,所以我们就需要同步两者之间的数据就行了。那如何实现两者之间的数据一致性呢?这里mysql通过两阶段提交来实现。
两阶段提交
- prepare阶段:innodb prepare,执行操作,写入redo log;
- commit阶段:写入bin log innodb commit(内存操作)。
两阶段提交中,当已经记录到bin log 中之后,就可以认为数据已经持久化了,数据可以传给从数据库了。
开启bin log
log-bin=ON
binlog-format=row//选择row模式
server_id=1//配置mysql replaction需要定义,不能和canal和slaved重复
参数:
binlog_cache_size:日志缓存大小,默认3MB。
sync_binlog:设置多少次事务刷盘,默认1,建议设置成0。
总结:redo log能实现crach-safe主要还是因为事务的原子性,还有就是redo log是物理日志。bin log不能实现crach-safe的主要原因还是bin log是server层的日志,没有事务的特点,导致数据的不一致。但是bin log的用处在于主从复制,而又引发的一个问题就是bin log 和redo log数据一致性的问题,而两阶段提交就完美的解决了这个问题。
参考文章:https://blog.csdn.net/lzhcoder/article/details/88814364