zoukankan      html  css  js  c++  java
  • innodb redo buffer的认识

                               InnoDB Redo的结构漫谈(1)
                               
                               作者:@明天会更好(群号:196380905)
                               
    1.Redo 日志:
            redo日志的结构是物理到页,逻辑到记录;采用的是物理逻辑日志。innodb redo日志是基于mini-transaction实现的。
            每个重做日志块是512个字节,也就意味着log buffer中也是以512个字节的块组织的。每个mini-transaction 会有一
            个mtr的结构,这个mtr的结构封装了未被写入到log buffer的日志,mtr结构有log成员,该成员就是日志的结构。log_t
            是代表log buffer的结构,mysqld运行实例中只维护一个sys_log实例(lot_t sys_log).
                sys_log维护了我们制定的innodb_log_buffer_size制定的大小的redo buffer.该内存区域在sys_log->buf维护了这个内存区域。
                
                    
                    
                    redo buffer 有如下三个结构:
                    
                    |----------------|
                    |  block header  |
                    |----------------|
                    |  records  logs |
                    |----------------|
                    |  block trialer |         
                    |----------------|
                      (log block 结构)
                      
             |----------|----------|----------|----------|
             |log block |log block |log block |log block |
             |----------|----------|----------|----------|
                        (log buffer 组织方式)
                        
        log buffer 中的头和尾部在源码中定义:
          /* 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 */
        
        mini-transactions是mtr的缩写,mtr会把一组log record集中起来,然后写入到log buffer.
            /* Mini-transaction handle and buffer */
                struct mtr_t{
                #ifdef UNIV_DEBUG
                    ulint        state;    /*!< MTR_ACTIVE, MTR_COMMITTING, MTR_COMMITTED */
                #endif
                    dyn_array_t    memo;    /*!< memo stack for locks etc. */
                    dyn_array_t    log;    /*!< mini-transaction log */
                    unsigned    inside_ibuf:1;
                                /*!< TRUE if inside ibuf changes */
                    unsigned    modifications:1;
                                /*!< TRUE if the mini-transaction
                                modified buffer pool pages */
                    unsigned    made_dirty:1;
                                /*!< TRUE if mtr has made at least
                                one buffer pool page dirty */
                    ulint        n_log_recs;
                                /* count of how many page initial log records
                                have been written to the mtr log */
                    ulint        n_freed_pages;
                                /* number of pages that have been freed in
                                this mini-transaction */
                    ulint        log_mode; /* specifies which operations should be
                                logged; default value MTR_LOG_ALL */
                    lsn_t        start_lsn;/* start lsn of the possible log entry for
                                this mtr */
                    lsn_t        end_lsn;/* end lsn of the possible log entry for
                                this mtr */
                #ifdef UNIV_DEBUG
                    ulint        magic_n;
                #endif /* UNIV_DEBUG */
                };
    
                dyn_block_t的定义:
    
                /** A block in a dynamically allocated array */
                struct dyn_block_t;
                /** Dynamically allocated array */
                typedef dyn_block_t        dyn_array_t;
    
                /** This is the initial 'payload' size of a dynamic array;
                this must be > MLOG_BUF_MARGIN + 30! */
                #define    DYN_ARRAY_DATA_SIZE    512
                /*#################################################################*/
    
                /** @brief A block in a dynamically allocated array.
                NOTE! Do not access the fields of the struct directly: the definition
                appears here only for the compiler to know its size! */
                struct dyn_block_t{
                    mem_heap_t*    heap;    /*!< in the first block this is != NULL
                                if dynamic allocation has been needed */
                    ulint        used;    /*!< number of data bytes used in this block;
                                DYN_BLOCK_FULL_FLAG is set when the block
                                becomes full */
                    byte        data[DYN_ARRAY_DATA_SIZE]; //真实的日志数据
                                /*!< storage for array elements */
                    UT_LIST_BASE_NODE_T(dyn_block_t) base;
                                /*!< linear list of dyn blocks: this node is
                                used only in the first block */
                    UT_LIST_NODE_T(dyn_block_t) list;
                                /*!< linear list node: used in all blocks */
                #ifdef UNIV_DEBUG
                    ulint        buf_end;/*!< only in the debug version: if dyn
                                array is opened, this is the buffer
                                end offset, else this is 0 */
                    ulint        magic_n;/*!< magic number (DYN_BLOCK_MAGIC_N) */
                #endif
                };
    
    
    2.mini-transaction log的调用方法的逻辑:
    
       mtr_commit
         ->mtr_log_reserve_and_write
            ->log_write_low //该函数是把mtr->log写入到空闲的log buffer中
            /************************************************************//**
            Writes the contents of a mini-transaction log, if any, to the database log. */
            static void mtr_log_reserve_and_write(mtr_t*    mtr)    /*!< in/out: mtr */
                    --->
                    /************************************************************//**
                    Writes to the log the string given. It is assumed that the caller holds the
                    log mutex. */
                    UNIV_INTERN void log_write_low(byte*    str/*!< in: string */,        ulint    str_len/*!< in: string length */)    
  • 相关阅读:
    如何在linux系统中设置静态ip地址
    spring 学习
    java 反射机制和invoke方法
    CentoS7装机
    eclipse 添加jar包的方式
    No-args constructor for class does not exist. Register an InstanceCreator with G
    freemarker页面如何获取绝对路径basePath
    MySQL备份还原
    MySQL用户授权与权限
    CentOS7修改SSH远程连接端口
  • 原文地址:https://www.cnblogs.com/innobase/p/4724528.html
Copyright © 2011-2022 走看看