Mysql InnoDB Redo log( 四 )

oldest_modification=8916那么说明redo log日志对应lsn值小于8916的均可被覆盖,checkpoint_lsn的值会被设置为8916

  • 将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 。
    在mysql进行崩溃恢复的时候,只需要从checkpoint_lsn在日志文件组中对应的偏移量开始 , 扫描到第一个log_block_hdr_data_len值不为512的block为止
    3.如何进行崩溃恢复现在确定了需要恢复的redo log , 那么如何进行恢复昵,每一个redo log格式如下
    Mysql InnoDB Redo log

    文章插图
    3.1化随机io为顺序io其space id记录了表空间号,page number记录了页号,也许这一堆redo log整体上表空间号,页号是不具备顺序的 , 如果直接遍历每一个redo log然后对表空间中的页进行恢复,是会带来很多随机io的,所以innodb使用hash表进行优化,将相同表空间号和页号作为key,这样相同表空间和页的日志就会在同一个hash桶中形成链表中,然后遍历每一个hash表的操作,一次性将一个页进行恢复,化随机io为顺序io
    3.2跳过不需要刷新页首先小于最近一次checkpoint_lsn的redo log肯定是不需要进行恢复,但是大于的也不一定需要恢复,因为可能在做崩溃前的checkpoint的时候,后台线程也许将LRU链表和flush链表中的一些脏页刷新到磁盘了,那么恢复的时候这些脏页也不需要进行恢复 。那么怎么判断这些不需要恢复的脏页昵?——每一个页面具备file header,其中有一个属性为file_page_lsn的属性,记录了最近一次修改页面时对应的lsn值(即脏页在buffer pool控制块中的newest_modification)如果执行某次checkpoint发现页中的lsn大于最近一次checkpoint的checkpoint_lsn的时候,那么说明此页不需要进行更新 。

    推荐阅读