redo log

  • 什么是redo log
  • MySQL是如何写入redo log的
  • redo log block
  • redo log buffer
  • redo log buffer的刷盘

什么是redo log

redo log记录了对哪个表空间的哪个数据页中偏移量为xx的地方更新了多少个字节的什么数据

每次MySQL提交事务时,都会写入redo log,为了防止数据页还没有刷盘的情况下MySQL宕机导致数据丢失的情况,MySQL对redo log的写入是顺序写入,并且每次写入的字节数都很少,它的结构如下:

  • 日志类型:MLOG_1BYTE、MLOG_2BYTE、MLOG_WRITE_STRING等等
  • 表空间ID
  • 数据页号
  • 数据页偏移量:数据长度,当日志类型为MLOG_WRITE_STRING时存在,因为此时无法知道到底修改了多少字节的数据
  • 具体修改为什么数据

MySQL是如何写入redo log的

在对数据页进行操作的时候,首先会将磁盘上的数据页读入到buffer pool中,然后在buffer pool对缓存页(数据页在buffer pool中的名称)进行增删改查操作,每次修改数据页,提交事务的时候都会写入一条redo log,在MySQL中,一条一条的redo log是顺序写入的,它们不是直接写入磁盘文件,而是先写入到redo log block中,该block的结构如下:

  • header
    • (4)blockNo:该block的唯一编号
    • (2)dataLength:数据长度,当前block中存储了多少字节的数据
    • (2)first record group:第一个日志分组偏移量
    • (4)checkpoint on
  • body:具体的redo log
  • trailer

redo log buffer

那么MySQL会直接将block写入磁盘吗?其实不是的,在MySQL中,还有一块内存区域叫redo log buffer,顾名思义,它是用于存放redo log的缓冲区,默认大小为16MB,实际上里面存储的就是一个一个的redo log block

当需要写入redo log时,就会从第一个redo log block开始写入,写满一个换一个,当所有block都满了之后,MySQL就会强制将redo log buffer刷入磁盘

在执行事务的过程中,可能会涉及到多个redo log,那么这多个redo log就组成了一个redo log group,执行事务的过程中首先会将该事务中的redo log收集起来,等待事务执行完成,再统一写入到redo log block中,如果redo log过多,可能会存放到两个block中,同样的,如果redo log比较少,可能多个redo log group会存放到同一个block中

redo log buffer的刷盘

当出现以下四种情况,会触发redo log buffer的刷盘:

  • 当redo log buffer中的redo log超过了其存储阈值的一半时
  • 事务提交时
  • MySQL后台线程每隔一秒执行一次redo log的刷盘
  • MySQL退出时