当执行CRUD的时候,从磁盘加载数据页到buffer pool的缓存页中,然后对数据页执行增删改,同时还会写redo log,后续不定时把缓存页刷回磁盘中。
07_redo log - 图1

1.redo log结构

redo log本质记录的就是对某个表空间的某个数据页的某个偏移量的地方修改了几个字节的值,具体修改的值是什么,里面需要记录的就是表空间号+数据页号+偏移量+修改几个字节的值+具体的值
根据修改数据页里几个字节的值,redo log划分了不同的类型,MLOG_1BYTE类型的日志就是修改了1个字节的值,MLOG_2BYTE类型就是修改了2个字节的值,以此类推,还有修改了4个、8个字节的值的日志类型,如果修改了一大串值,类型就是MLOG_WRITE_STRING。
一条redo log大致结构为:日志类型,表空间ID,数据页号,数据页中的偏移量,修改数据长度(如果类型是MLOG_WRITE_STRING),具体修改的数据。

2.redo log block

redo log并不是将数据一条一条直接写入磁盘的,而是用redo log block来存放多个单行日志。
一个redo log block是512字节,这个redo log block分为3部分,一个是12字节的header块头,一个是496字节的body块体,一个是4字节的trailer块尾。
12字节的header又分为4个部分:

  • 4个字节的block no,块唯一编号;
  • 2个字节的data length,block里写入了多少数据;
  • 2个字节的first record group,每个事物都会有多个redo log,即一组redo log,这个block里的第一组redo log的偏移量,就是这2个字节存储的;
  • 4个字节的checkpoint on。

07_redo log - 图2
如果要写第一个redo log,需要先在内存里把这个redo log弄到一个redo log block数据结构中,等内存中的一个redo log block的512字节满了后,再一次性把这个redo log block写入磁盘文件。
07_redo log - 图3

3.redo log buffer

redo log buffer就是在MySQL启动的时候,就跟操作系统申请一块连续的内存空间,里面划分出N多个空的redo log block,当所有redo log block满了,会强制把redo log block刷入磁盘中。
通过设置MySQL的innodb_log_buffer_size可以指定这个redo log buffer的大小,默认是16MB。
当执行一个事务的过程中,会有多个增删改操作,那么就会有多个redo log,多个redo log就是一组redo log,当所有操作执行完成,再把这一组redo log写入到redo log buffer中的block中。
如果一组redo log太多,可能会存放在两个redo log block中。

4.redo log buffer刷入磁盘

  1. 如果写入redo log buffer的日志已经占据了redo log buffer总容量的一半,会直接把redo log刷入到磁盘文件;
  2. 一个事务提交的时候,必须把它的redo log所在的redo log block都刷入到磁盘文件,只有这样,当事务提交之后,修改的数据才不会丢失;
  3. 后台线程定时刷新,每隔1秒就会把redo log buffer里面的redo log block刷入到磁盘文件;
  4. MySQL关闭的时候,redo log block都会刷入到磁盘文件。