InnoDB源码分析--事务日志(二)

    原创文章,转载请标明原文链接:http://www.cnblogs.com/wingsless/p/5708992.html

    昨天写了有关事务日志的一些基本点(http://www.cnblogs.com/wingsless/p/5705314.html),今天结合我最近的学习成果继续总结事务日志的知识点。

   三 日志结构

     我们都知道InnoDB最小的存储单元叫做页(page)或者块(block),日志系统也是如此,它是一个512字节的块,被这个参数定义:OS_FILE_LOG_BLOCK_SIZE。

     一个块肯定不会只有存储数据这么简单,肯定是有头部和尾部写一些信息进去的,而这在代码里很好找:

     

/* Offsets of a log block header */
#define    LOG_BLOCK_HDR_NO    0    /* block number which must be > 0 and
                    is allowed to wrap around at 2G; the
                    highest bit is set to 1 if this is the
                    first log block in a log flush write
                    segment */
#define LOG_BLOCK_FLUSH_BIT_MASK 0x80000000UL
                    /* mask used to get the highest bit in
                    the preceding field */
#define    LOG_BLOCK_HDR_DATA_LEN    4    /* number of bytes of log written to
                    this block */
#define    LOG_BLOCK_FIRST_REC_GROUP 6    /* offset of the first start of an
                    mtr log record group in this log block,
                    0 if none; if the value is the same
                    as LOG_BLOCK_HDR_DATA_LEN, it means
                    that the first rec group has not yet
                    been catenated to this log block, but
                    if it will, it will start at this
                    offset; an archive recovery can
                    start parsing the log records starting
                    from this offset in this log block,
                    if value not 0 */
#define LOG_BLOCK_CHECKPOINT_NO    8    /* 4 lower bytes of the value of
                    log_sys->next_checkpoint_no when the
                    log block was last written to: if the
                    block has not yet been written full,
                    this value is only updated before a
                    log buffer flush */
#define LOG_BLOCK_HDR_SIZE    12    /* size of the log block header in
                    bytes */

       

/* Offsets of a log block trailer from the end of the block */
#define    LOG_BLOCK_CHECKSUM    4    /* 4 byte checksum of the log block
                    contents; in InnoDB versions
                    < 3.23.52 this did not contain the
                    checksum but the same value as
                    .._HDR_NO */
#define    LOG_BLOCK_TRL_SIZE    4    /* trailer size in bytes */

 

       画张图:

       

      头部长度是12字节,尾部长度是4字节,代码中标明了头尾的长度,其他的都是偏移量,因此每个部分的长度也就是下一个偏移量减去当前值。这么算下来,实际上能存储数据的部分只有496字节了,这部分网上很多资料里都叫做log data,我在这里也这么叫吧。

      头部里我觉得有意思的一个地方是这个:LOG_BLOCK_FIRST_REC_GROUP,这是block里第一个日志的起始位置的偏移量。例如一个日志有500字节,那么写完了一个块之后,还有4个字节会被写在下一个块里,此时又有一个100字节的页写到了第二个block里(起个名字叫log2吧),于是第二个块里变成了这种情况:

     

       第二个日志从16位置开始,到116位置结束,这个时候LOG_BLOCK_FIRST_REC_GROUP值会写什么呢?很显然是16,因为log2才是这个block里的第一个页。

       知道了日志结构,其实只是了解redo log的第一步,因为redo log是InnoDB实现事务的重要手段,里面的水很深,我也会不断地把我的学习心得写在这里,并不断地补充写好的东西。

       原创文章,转载请标明原文链接:http://www.cnblogs.com/wingsless/p/5708992.html

posted @ 2016-07-26 21:21  wingsless  阅读(1219)  评论(0编辑  收藏  举报