Mysql redo log和bin log区别
redo log 是InnoDB存储引擎层的日志,其他存储引擎不存在的 bin log是服务层的日志,不区分存储引擎
redo log 是物理日志,记录的是"在 XXX 页上做了 XXX 修改"; binlog 是逻辑日志,比如" 给 id = 2 这一行的 c 字段加 1"
redo log 是有固定大小的,所以它的空间会用完,如果用完的话,一定要进行一些写入磁盘的操作才可以继续; binlog 是可以追加写入的,也就是 binlog 没有空间的概念,一直写就行了

redo log的主要作用
1.发生宕机等事故时,通过redolog恢复数据,保证事务的持久化
2.当update等操作附带的where条件,需要先检索再更新。如果数据量很大,查询复杂这样直接处理再写到磁盘IO代价很大,
因此先记录在redo log, 再写入内存Buffer Pool,这样就算update成功了。InnoDB等到合适时机再把数据异步刷到磁盘。(WAL 技术,也就是 WriteAheadLogging ,核心就是先写日志,再写磁盘)
redo log 不能一直写吧?如果更新操作一直写入到 redo log 中的话,不限制大小的话,可能服务器上的存储空间都被 redo log 给占满了
所以redo log写一段时间后会写入磁盘,然后即时清理
所以 InnoDB 的 redo log 是固定大小的,比如我们配置了一组 4 个文件,每个文件大小是 1GB ,那么它的操作可能就会这样:

主要就是 write pos 和 checkpoint , write pos 比较好理解,它就是当前记录的位置,有需要记录的操作就从当前位置向后移,等把 ib_logfile_3 写完之后,就回到 ib_logfile_0 文件开头继续写
checkpoint 是当前要擦除的位置,就是 InnoDB 引擎不是会在恰当的时候,将这些操作进行持久化,更新到磁盘上去,那持久化之后的数据是不是就可以擦除了
write pos 和 checkpoint 之间的部分就是可以用来记录操作的部分,那么如果 write pos 和 checkpoint 相遇了怎么办?相遇了是不是说明这个时候分配的 redo log 大小用完了,那这时候就不能再进行更新操作了,必须停下来处理一下,将 checkpoint 往前推推才行
就是因为有了 redo log ,所以 InnoDB 才可以保证即使数据库发生了异常重启,也没关系,之前提交的记录都还在,只需要根据 redo log 里面的记录进行相应恢复就可以了
udpate一条例子
我现在要给 id = 2 这一行的 c 字段加 1,到 MySQL 层面
1.首先写入redolog,在内存中的redolog buffer中,
2.同时异步的去找到这条 id = 2 的数据的page页,将该page页读取到内存Buffer Pool,并修改Buffer Pool中的内存页,形成脏页
3.当事务提交时,会触发redologBuffer刷盘,并将状态标记为prepare,(刷盘行为由参数 innodb_flush_log_at_trx_commit 控制:
=1:每次提交都刷盘(默认,保证持久性)。=0或=2:可能延迟刷盘(性能优化,但可能丢失事务))
4.写入 binlog日志并刷盘(
- 刷盘行为由参数
sync_binlog控制:=1:每次提交都刷盘(默认,保证主从一致性)。=0:依赖 OS 刷盘(可能丢失数据))
6.redolog更新状态为 commit,提交成功
这就是传说中的的”两阶段提交“,保证了redo log 和 bin log 数据一致性
第一步,将更新操作写到redolog,再刷到磁盘,同时异步的更新到内存中的表page页 此时为脏页。此时redo log 处于prepare状态,
第二步,生成binlog记录刷入磁盘,redo log 从prepare 更新到commit状态
后续,等Buffer Pool内存空间不足,将内存中的脏页 批量刷到磁盘。

浙公网安备 33010602011771号