MySQL-Innodb-BufferPool内存组织

2020-10-18  本文已影响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);
}
上一篇下一篇

猜你喜欢

热点阅读