MySQL-redo log 和 binlog
redo log部分
为什么需要redo log?
简单的说,如果每次更新数据库的操作,都去更新磁盘的话,开销是很大的。通过引入redo log日志,其中记录了每次更新的操作明细,在系统不繁忙的时候,再更新到磁盘中,可以节省开销。
最新修改:
redo log 最主要的作用就是用于数据库异常宕机的恢复工作。
假如数据库永远不会发生异常宕机,那么其实根本不需要redo log,因为innodb中有线程不断的做把脏页刷新到磁盘的工作,数据库如果一直不宕机,就不会出现问题。
被划掉的线的部分的理解的产生是因为在极客时间《mysql实战45讲》的课程中,老师就是这么说的,所以就直接这么写了。但在后续的学习中,我查阅了《MySQL技术内幕-InnoDb存储引擎的实现》这本书,发现了最开始的理解并不准确,所以进行了修改。
redo log的实现
redo log是一个环,大小是固定的,文件个数和大小是可以配置的。其中有两个指针,write和checkpoint,分别对应可以写入的位置,和已经刷新到磁盘的位置。
当write追上了checkpoint,说明已经没有空闲的位置可以写入了,就需要刷新一下,保证有位置可以写入。
binlog部分
redo log 和 binlog的区别
- redo log是 innodb存储引擎特有的;binlog是server层,属于共有的
- redo log是物理日志,记录在某个数据页的修改;binlog是逻辑日志
- redo log是一个环,循环写;binlog是追加写,不会覆盖以前的日志
- redo log用于异常重启恢复;binlog用于备份
一条更新语句的执行过程(redo log和binlog的配合)
- 执行器调用引擎接口写入新数据
- 引擎把更新操作记录到 redo log中,此时redo log为prepare状态
- 执行器生成这个操作的binlog,并写入磁盘
- 执行器调用引擎的事务提交接口,引擎把redo log的状态改为commit
prepare和binlog是如何保证一致性的?
- prepare阶段
- binlog写入阶段
- commit阶段
在2阶段之前崩溃时:
- 重启恢复:发现没有commit,回滚
- 备份恢复:没有binlog
保持了一致性
在3阶段之前崩溃时:
- 重启恢复:虽没有commit,但是binlog有,并且一致,所以恢复
- 备份恢复:有binlog
保持了一致性
最佳实践部分
- innodb_flush_log_at_trx_commit 参数建议设置为1,每次更新操作,redo log都会刷新到磁盘
- sync_binlog 参数建议设置为1,每次更新操做,binlog会刷新到磁盘