Mysql InnoDB Redo log( 二 )


三丶Mini-Transactionmysql把底层页面的一次原子访问过程称为一个Mini-Transaction(MTR)(比如向B+树中插入一条记录的过程算作一个MTR , 即使这个sql涉及到多个B+树)一个MTR可以包含一组redo log , 在进行崩溃恢复的时候需要把这一组MTR看作是一个不可分割的整体(B+树中插入一条记录 , 可能涉及到叶子节点 , 非叶子点的改动 , 不能说只新增了叶子节点 , 但是没用更新非叶子节点 , 需要保证这个过程的原子性)
一个事务可以包含多个语句 , 一个语句可以包含多个MTR , 一个MTR可以包含多个redo log日志 , 那么innodb是如何确认多个redo log属于一个MTR的昵

Mysql InnoDB Redo log

文章插图
多个redo log以最后一条类型为MLOG_MULTI_REC_END类型的日志结尾 , 那么视为前面的redo log为同一MTR中的日志 。系统在进行崩溃恢复的时候 , 只有解析到MLOG_MULTI_REC_END类型的日志的时候 , 才认为解析到了一组完整的redo log日志 , 才会进行恢复 。
有些需要保证原子性的操作 , 只会产生一条redo log , 比如更新Max Row ID(innodb在用户没用指定主键的时候 , 将此值存储在页中 , 没增大到256的整数倍的时候 , 才会更新写回磁盘) , 这个时候会将其的type字段的第一个比特置为1 , 表示这个单个redo log 便是一个原子性操作 , 而不是加上一个MLOG_MULTI_REC_END类型的日志 。
四丶redo log日志写入过程1.redo log block
Mysql InnoDB Redo log

文章插图
innodb 将通过MTR生成的redo log放在大小为512字节的block中 , 其中存储redo log的部分只有log block body其余的两部分存储一些统计信息
  • log block header
    • log_block_hdr_no:每一个block 具备一个大于0的唯一编号 , 此属性便是记录编号值
    • log_block_hdr_data_len:记录当前lock block使用了多少字节(从12开始 , 因为lock block header占用了12字节) , 随着越来越多的日志写入block最后最大为512字节
    • log_block_first_rec_group:一个MTR包含多个日志 , 这个字段记录该block中第一个MTR生成redo log日志记录组的偏移量 。
    • log_block_checkpoint_no:表示checkpoint的序号
  • log block trailer
    • log_block_check_sum:表示block检验和 , 用于正确性校验
2.redo log buffer为了解决磁盘写入过慢的问题 , innodb采用了redo log buffer , 写入redo log不会直接写入磁盘 , 而是在服务启动的时候申请一片连续的内存空间 , 用作缓冲redo log的写入
Mysql InnoDB Redo log

文章插图
innodb_log_buffer_size可以指定其大小 , 默认16mb
3.redo log写入log bufferinnodb保存了一个buf_free的全局变量用于记录log buffer中空闲位置的偏移量 , 让后续redo log的写入从buf_free的位置开始写 。
不同的事务是可以并发运行的 , 并发的写入redo log buffer中 , 每当一个MTR执行完成时 , 伴随着该MTR生成的redo log被写入到log buffer中 , 多个不同事务的MTR可能时交替写如到log buffer中的
五丶redo log持久化1.redo log buffer中的内容何时持久化到磁盘MTR运行过程中产生的一组redo log会在MTR结束的时候被复制到log buffer中 , 但是何时落盘昵?

经验总结扩展阅读