percona8.0 Innodb buf_pool 创建过程源码分析
innodb 支持多个buf_pool 实例;
//入口函数 buf_pool_init;total_size pool的总大小,n_instances 实例个数;
buf_pool_init(ulint total_size, bool populate, ulint n_instances) {
…
buf_pool_ptr =
(buf_pool_t *)ut_zalloc_nokey(n_instances * sizeof *buf_pool_ptr);
/*初始化对 n_instances个buf_pool实例所需的结构buf_pool_t 所需的空间/
for (ulint id = i; id < n; ++id) {
threads.emplace_back(std::thread(buf_pool_create, &buf_pool_ptr[id], size,
id, &m, std::ref(errs[id]), populate));
}
/** 每一个buf_pool 实例的创建由 buf_pool_create 负责***/
…
}
/* 每一个buf_pool 实例创建入口 */
buf_pool_create(…) {
…
buf_pool->chunks = reinterpret_cast<buf_chunk_t *>(
ut_zalloc_nokey(buf_pool->n_chunks * sizeof(*chunk)));
/buf_pool 的 chunks 是一个 buf_chunk_t 数组的首地址。这个数组的内存空间是连续的,向系统直接申请的,不是来自buf_pool 本身/
…
do {
if (!buf_chunk_init(buf_pool, chunk, chunk_size, populate, mutex)) {
…
}
} while(++chunk < buf_pool->chunks + buf_pool->n_chunks)
/每一个chunk里面的mem 指向一片连续的内存 默认128M;buf_chunk_init 主要是初始化这个mem;循环把chunks 的每一个chunk都初始化完。至此 可知 buf_pool 是一段段的chunk组成,那么chunk内部又是如何划分的呢 参考 buf_chunk_init 函数/
…
}
/初始化chunk/
buf_chunk_t buf_chunk_init(…) {
…
if (!buf_pool->allocate_chunk(mem_size, chunk, populate)) {
return (NULL);
}
/为每一个chunk开辟mem_size默认128M的连续空间,起始地址赋给 chunk->mem/
…
chunk->blocks = (buf_block_t *)chunk->mem;//blocks指向chunk->mem的起始地址。
…
frame = (byte *)ut_align(chunk->mem, UNIV_PAGE_SIZE);
/frame指向按页对齐的
mem向后的首地址/
chunk->size = chunk->mem_pfx.m_size / UNIV_PAGE_SIZE - (frame != chunk->mem);
/**chunk->size 表示一共有多少个页**/
{
ulint size = chunk->size;
while (frame < (byte *)(chunk->blocks + size)) {
frame += UNIV_PAGE_SIZE;//表示一个页的起始地址
size--;
}
chunk->size = size;
}
/这段代码 把每一组block和page对应起来(brock->frame=frame),并把当前buff_pool实例的地址初始化到block上 并把block的首地址(等同于block->page的首地址)放进 free 链表中/
…
buf_pool_register_chunk(chunk);
/最后把chunk注册到当前所有 buff_pool 实例公用的 buf_chunk_map_reg 中/
}