redo日志和undo日志
本篇文章非原创,原创地址:https://juejin.im/entry/5ba0a254e51d450e735e4a1f
1. redo log 和 bin log的区别
- 所处层级不同:bin log位于应用层,任何存储引擎都可以用,redo log作用于存储引擎层,只有innodb使用;因此常用bin log来恢复数据
- 格式不同:bin log是sql,redo log是物理格式的数据
- 提交方式不同:bin log在事务提交时一次性写入缓存中的日志,redo log在数据准备修改前会写入,修改完成后又会写入一次。
- 记录顺序不同:bin log一次性提交,所以一个事务只对应一次记录,redo log会多次提交,一个事务会对应多个记录,但是最后一次提交的记录会覆盖前面的记录。
- redo log具有幂等性,二进制则无(这里原作者给的理由没有很理解)
2. redo log持久化流程

mysql还可以通过参数innodb_flush_log_at_trx_commit来决定刷新日志缓存到日志文件的频率,这个参数有0,1,2三个选项,主要是考虑安全和效率。
3.日志块
innodb存储引擎中,redo log以块为单位进行存储的,每个块占512字节,这称为redo log block。所以不管是log buffer中还是os buffer中以及redo log file on disk中,都是这样以512字节的块存储的。每个redo log block由3部分组成:日志块头、日志块尾和日志主体。其中日志块头占用12字节,日志块尾占用8字节,所以每个redo log block的日志主体部分只有512-12-8=492字节。

日志块头记录了:
- log_block_hdr_no:该日志块在redo log中的位置ID
- log_block_hdr_data_len:该log_block中已记录的log大小
- log_block_first_rec_group:该log中第一个log的开始偏移量
- lock_block_checkpoint_no:写入检查点信息的位置
关于log block块头的第三部分 log_block_first_rec_group ,因为有时候一个数据页产生的日志量超出了一个日志块,这是需要用多个日志块来记录该页的相关日志。例如,某一数据页产生了552字节的日志量,那么需要占用两个日志块,第一个日志块占用492字节,第二个日志块需要占用60个字节,那么对于第二个日志块来说,它的第一个log的开始位置就是72字节(60+12)。如果该部分的值和 log_block_hdr_data_len 相等,则说明该log block中没有新开始的日志块,即表示该日志块用来延续前一个日志块。
4. log group和redo log file
组内redo log file的数量由变量 innodb_log_files_group 决定,默认值为2,即两个redo log file。这个组是一个逻辑的概念,并没有真正的文件来表示这是一个组,但是可以通过变量 innodb_log_group_home_dir 来定义组的目录,redo log file都放在这个目录下,默认是在datadir下。