美文网首页
MySQL-Innodb-BufferPool内存组织

MySQL-Innodb-BufferPool内存组织

作者: 多血 | 来源:发表于2020-10-18 15:21 被阅读0次

    内存组织


    bufferpool内存 (1).png

    Chunk:包括两部分:数据页和数据页对应的控制体,控制体中有指针指向数据页。Buffer Chunks是最低层的物理块,在启动阶段从操作系统申请,直到数据库关闭才释放。数据页里面不一定都存的是用户数据,开始是控制信息,比如行锁,自适应哈希等。
    BUffer Pool中缓存的数据页类型有: 索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)、InnoDB存储的锁信息(lock info)、数据字典信息(data dictionary)等。
    调用栈

    buf_pool_init_instance
    ----buf_chunk_init
    

    具体函数

    /********************************************************************//**
    Allocates a chunk of buffer frames.
    @return chunk, or NULL on failure */
    static
    buf_chunk_t*
    buf_chunk_init(
    /*===========*/
        buf_pool_t* buf_pool,   /*!< in: buffer pool instance */
        buf_chunk_t*    chunk,      /*!< out: chunk of buffers */
        ulint       mem_size)   /*!< in: requested size in bytes */
    {
        buf_block_t*    block;
        byte*       frame;
        ulint       i;
    
        /* Round down to a multiple of page size,
        although it already should be. */
        mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE);
        /* Reserve space for the block descriptors. */
        mem_size += ut_2pow_round((mem_size / UNIV_PAGE_SIZE) * (sizeof *block)
                      + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
    
        DBUG_EXECUTE_IF("ib_buf_chunk_init_fails", return(NULL););
    
        chunk->mem = buf_pool->allocator.allocate_large(mem_size,
                                &chunk->mem_pfx);
    
        if (UNIV_UNLIKELY(chunk->mem == NULL)) {
    
            return(NULL);
        }
    
        /* Allocate the block descriptors from
        the start of the memory block. */
        chunk->blocks = (buf_block_t*) chunk->mem;
    
        /* Align a pointer to the first frame.  Note that when
        os_large_page_size is smaller than UNIV_PAGE_SIZE,
        we may allocate one fewer block than requested.  When
        it is bigger, we may allocate more blocks than requested. */
    
        frame = (byte*) ut_align(chunk->mem, UNIV_PAGE_SIZE);
        chunk->size = chunk->mem_pfx.m_size / UNIV_PAGE_SIZE
            - (frame != chunk->mem);
    
        /* Subtract the space needed for block descriptors. */
        /* 通过指针位置来判断chunk总共能容下多少个buf_block_t+UNIV_PAGE_SIZE */
        /* UNIV_PAGE_SIZE默认为16k,
        #define UNIV_PAGE_SIZE ((ulint) srv_page_size)
        ulong srv_page_size = UNIV_PAGE_SIZE_DEF;
        #define UNIV_PAGE_SIZE_DEF (1 << UNIV_PAGE_SIZE_SHIFT_DEF)
        #define UNIV_PAGE_SIZE_SHIFT_DEF 14
        1<<14  =2^14=16384=16K
        */
        {
            ulint   size = chunk->size;
    
            while (frame < (byte*) (chunk->blocks + size)) {
                frame += UNIV_PAGE_SIZE;
                size--;
            }
    
            chunk->size = size;
        }
    
        /* Init block structs and assign frames for them. Then we
        assign the frames to the first blocks (we already mapped the
        memory above). */
    
        block = chunk->blocks;
    
        for (i = chunk->size; i--; ) {
            /*初始化每个block*/
            buf_block_init(buf_pool, block, frame);
            UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE);
    
            /* Add the block to the free list */
            UT_LIST_ADD_LAST(buf_pool->free, &block->page);
    
            block++;
            frame += UNIV_PAGE_SIZE;
        }
    
        buf_pool_register_chunk(chunk);
        return(chunk);
    }
    

    相关文章

      网友评论

          本文标题:MySQL-Innodb-BufferPool内存组织

          本文链接:https://www.haomeiwen.com/subject/dveypktx.html