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);
}