MySQL:Innodb crash recovery一些代码

简单记录可能还理解,做个笔记,不深入:

公众号 MySQL学习


http://mysql.taobao.org/monthly/2015/06/01/
buf_dblwr_init_or_load_pages 
初始化dblwr从double write中,写入到内存
Recovering partial pages from the parallel doublewrite buffer at /opt/my_mysql/data/xb_doublewrite
recv_recovery_from_checkpoint_start 总是进行恢复  we always do a 'recovery' at startup
    srv_force_recovery >= SRV_FORCE_NO_LOG_REDO 则直接跳过恢复步骤
  信息级别信息 "The user has set SRV_FORCE_NO_LOG_REDO on, skipping log redo"
    ->recv_find_max_checkpoint
  找到最大的chk block 有2个chk block循环写入,
    ->log_group_header_read
  读取chk block到 log_sys(log buffer的chk buffer)
  buf = log_sys->checkpoint_buf;
    checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN); //获取chk lsn
    checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO);//获取chk的次数
  获取chk lsn/chk的次数
    ->recv_group_scan_log_recs带入形参找到的最大chk lsn和日志组,第一次调用带入的参数last_phase为false,任何log rec存储 开始解析 解析入hash结构 recv_sys->addr_hash 
   available_mem有效的内存来自innodb buffer
   首先向下以512对其chk lsn准备开始读取
   每次读取分片64K的日志,这里开启一个循环
      ->log_group_read_log_seg 读取64K的日志,到redo buffer的buffer中,读取为fil_io
      ->recv_scan_log_recs 输入参数主要带入64k的大小和chk lsn开始解析
     开启循环分块(512)进行日志检查。如果大于了?则解析结束,加入到解析buffer,结束条件未知
     data_len = log_block_get_data_len(log_block); //获取块中存储的数据,一般都是512 除非最后一个块或者不需要恢复
     如果输入的lsn大于上次解析lsn则说明有更多的redo需要进行解析,一般为64K,除非最后一个分片We have found more entries
     输出日志scanned_lsn > recv_sys->scanned_lsn,这里就代表不是干净关闭数据库,需要进行 recovery,因为需要扫描的
     lsn大于了redo中第一个lsn的位置,后面也会用到这个位置,recv_init_crash_recovery_spaces依赖这个比较看是否需要crash recovery,
     下列输出日志只输出一次 recv_init_crash_recovery(5.6这里进行dblr恢复)
     info级别"Log scan progressed past the checkpoint lsn  recv_sys->scanned_lsn(redo中第一个redo record的lsn);
        ->recv_sys_add_to_parsing_buf 加入到parsing buffer中,输入参数为 64K的分片和扫描到的lsn 
     循环结束,加入到解析缓存结束
     如果扫描次数为80次则输出一次日志或者结束,作为信息
      "Doing recovery: scanned up to log sequence number "
        ->recv_parse_log_recs 解析每条redo日志,根据不同的类型
         ->recv_parse_log_rec解析单个redo
           ->recv_parse_or_apply_log_rec_body尝试应用MLOG_FILE_*的日志类型
         ->recv_add_to_hash 加入到hash结构,根据space id和page no进行hash,等待应用
    ->如果需要进行crash recovery则进行 recv_needed_recovery进行判断在
    recv_init_crash_recovery_spaces 初始化需要用到的tablespace,输出日志,info级别
    Database was not shutdown normally!
    Starting crash recovery.
      ->buf_dblwr_process应用dblwr的断页信息
    ->如果内存不足(innodb buffer不足hash的全部日志存储在innodb buffer中)
    调用recv_group_scan_log_recs(,,ture)直接进行应用了。第二次调用recv_group_scan_log_recs
    ->trx_sys_init_at_db_start 初始化undo的page,用于crash recovery 可以不进行undo page的初始化进行启动 SRV_FORCE_NO_UNDO_LOG_SCAN
    ->recv_apply_hashed_log_recs进行日志应用
    ->recv_recovery_rollback_active 回滚事务  SRV_FORCE_NO_TRX_UNDO
    单独线程trx_rollback_or_clean_all_recovered  SRV_FORCE_NO_TRX_UNDO
    ->Binlog/InnoDB XA Recover
enum {
    SRV_FORCE_IGNORE_CORRUPT = 1,    /*!< let the server run even if it
                    detects a corrupt page */
    SRV_FORCE_NO_BACKGROUND    = 2,    /*!< prevent the main thread from
                    running: if a crash would occur
                    in purge, this prevents it */
    SRV_FORCE_NO_TRX_UNDO = 3,    /*!< do not run trx rollback after
                    recovery */ trx_rollback_or_clean_all_recovered
    SRV_FORCE_NO_IBUF_MERGE = 4,    /*!< prevent also ibuf operations:
                    if they would cause a crash, better
                    not do them */ ibuf_merge_or_delete_for_page
    SRV_FORCE_NO_UNDO_LOG_SCAN = 5,    /*!< do not look at undo logs when
                    starting the database: InnoDB will
                    treat even incomplete transactions
                    as committed */ trx_sys_init_at_db_start
    SRV_FORCE_NO_LOG_REDO = 6    /*!< do not do the log roll-forward
                    in connection with recovery */
};
请使用浏览器的分享功能分享到微信等