Mysql InnoDB Redo log( 五 )


执行一次checkpoint的操作可以分为两个步骤:

  1. 计算当前系统中可以覆盖的redo日志对应的lsn最大是多少
    Mysql InnoDB Redo log

    文章插图
    比如页A已经被刷盘了 , 此时flush链表的尾部便是页C , 其oldest_modification=8916那么说明redo log日志对应lsn值小于8916的均可被覆盖 , checkpoint_lsn的值会被设置为8916
  2. 将checkpoint_lsn和对应的日志文件组偏移量和这次checkpoint的编号写入到日志文件的管理信息中(checkpoint1 , checkpoint2)
    innodb使用checkpoint_no记录当前系统执行了多少次checkpoint , 根据lsn值计算除redo log日志的偏移量(lsn初始值为8704 , redo日志文件组偏移量为2048)计算得到checkpoint_offset,将checkpoint_no,checkpoint_lsn,checkpoint_offeset写回到redo log日志文件组管理信息中 , 关于checkpoint的信息 , 当checkpoint_no为偶数的时候会写回到checkpoint1 , 反之写入到checkpoint2中 。
8.控制事务提交时刷新redo log日志的选项——innodb_flush_log_at_trx_commit如果每次事务提交时都要求将redolog刷新到磁盘 , 那么带来的IO代价必然影响到引擎执行效率 , innodb具备innodb_flush_log_at_trx_commit配置项 , 来进行控制 。其选项值的不同代表着不同的策略:
  1. 0:表示事务提交不立即向磁盘同步redo log , 而是交由后台线程处理 。这样的好处时加快处理请求的速度 , 但是如果服务崩溃 , 后台线程也没来得及刷新redo log , 这时候会丢失事务对页面的处理
  2. 1:表示每次事务提交都需要将redo log同步到磁盘 , 可以保证事务的持久性 , 这也是innodb_flush_log_at_trx_commit的默认值
  3. 2:表示事务提交时 , 将redo log写到操作系统的缓冲区中 , 但是并不需要真正持久化到磁盘 , 这样事务的持久性在操作系统没有崩溃的时候还是可以保证 , 但是如果操作系统也崩溃那么还是无法保证持久性
六丶redo log用于崩溃恢复1.确定恢复的起点如果redo log对应的lsn小于checkpoint的话 , 意味这部分日志对应的脏页已经刷新到了磁盘中 , 是不需要进行恢复的 。但是大于checkpoint的redo log , 也许时需要恢复的 , 也许不需要 , 因为刷新脏页到磁盘是异步进行的 , 可能刷新脏页到磁盘但是没来得及修改checkpoint 。这时候需要从对应lsn的值为checkpoint_lsn的redo log开始恢复
redo log日志文件组有checkpoint1和checkpoint2记录checkpoint_lsn的值 , 我们需要选取最近发生的checkpoint信息 , 也就是将二者中的checkpoint_no拿出来比较比较 , 谁大说明谁存储了最近一次checkpoint信息 , 从而拿到最近发生checkpoint的checkpoint_lsn以及其对应的在redo 日志文件组中偏移量checkpoint_offset
2.确定恢复的终点
Mysql InnoDB Redo log

文章插图
写入redo log到redo日志文件中redo log block中时 , 是顺序写入的 , 先写满一个block再写下一个block , 每一个block的log block header部分有一个log_block_hdr_data_len来记录当前lock block使用了多少字节(从12开始 , 因为lock block header占用了12字节) , 随着越来越多的日志写入block最后最大为512字节`,所有如果此值小于512那么说明 , 当前这个block就是崩溃恢复需要扫描的最后一个block 。

经验总结扩展阅读