MySQL数据库InnoDB存储引擎 innodb_buffer_pool_size初始化详解

Buffer Pool导读

InnoDB Buffer Pool,可以说是InnoDB系统内部最重要的模块之一。通过系统参数innodb_buffer_pool_size,用户可以设置几G,几十G,乃至上百G的内存空间。那么,InnoDB存储引擎系统是如何管理这么大一片内存空间的呢?

 

l  Buffer Pool空间如何初始化?

l  Buffer Pool是通过什么数据结构管理的?

l  如何从Buffer Pool中分配page?

l  Buffer Pool已满情况下,如何替换?

l  Buffer Pool的LRU list,Flush list,Free list上分别有哪些操作?

l  LRU list flush与Flush list flush有和不同?

 

本文将详细调研InnoDB Buffer Pool实现,回答以上提到的各个问题。

Buffer Pool初始化

本章主要讨论MySQL数据库InnoDB存储引擎系统初始化的时候,是如何分配buffer pool的内存空间,并且如何初始化这一大块内存空间的。

初始化流程

源码处理流程:

srv0start.cc::innobase_start_or_create_for_mysql

// 若用户指定的buf pool size大于1G,则设置最大的等待线程数为50000

if(srv_buf_pool_size>= 1000*1024*1024)

srv_max_n_threads = 50000;

// 初始化buf pool主函数入口

// 1.每个buf pool的大小为srv_buf_pool_size除以instance个数

// 2. 调用buf_pool_init_instance函数,初始化各个buf pool实例

// 3. 计算buf_pool LRU list中,oldList部分所占的比率,初始化时默认为3/8

//      此参数在运行时可以调整,若设置了不同的old ratio,则涉及到调整

//      buf_pool->LRU_old指向的位置(LRU_old指向的是LRU list中位于old ratio处的

//     block位置;old ration调整,LRU_old需要相应的做出调整)

//      关于LRU list被划分为new与old两部分的原因及意义,可参考

//      The InnoDB Buffer Pool [1]

buf_pool_init(total_size, n_instances);

size = total_size / n_instances;                                                               流程1

// 2.1 初始化buf pool的free list

// 2.2 计算每个buf pool实际所需要的空间。空间必须按照page_size对齐;

//      必须为每个page分配一个内存block结构,用于管理内存page

// 2.3调用os_men_alloc_large函数,为buf pool分配大块内存

//      若使用了大页(Huge Page),则调用shmget, shmat, shmctl方法分配空间

//      若在windows平台下,则调用VirtualAlloc函数分配空间

//      若未使用MMAP,则调用ut_malloc_low函数分配空间

//      是使用MMAP,则调用mmap函数分配空间

//

// 2.4将分配出来的mem空间,按照page size对其,作为page的起点

// 2.5 将mem空间划分为两部分:前部分作为block结构的空间;后部分作为

//        page的空间,page空间每一个page的起始位置,必须按照page size对齐

//       block结构起始位置,为mem空间的0号位置;

//        page空间的起始位置,为预留足够的block结构之后的第一个frame位置

// 2.6 为每一个page指定一个block头结构,并初始化:初始化各种mutex与lock

//      每个block头结构的大小:MySQL 5.1,32位 304 bytes;64位800 bytes

// 2.7 将page加入buf pool的free list链表,等待分配

// 2.8 创建buf pool对应的page hash表,若page对应于文件中的一个页,则page

//      在hash表中存在,便于page在内存中的快速定位

buf_pool_init_instance();                                                                          流程2

UT_LIST_INIT(buf_pool->free);

buf_chunk_init();

mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE);

mem_size += ut_2pow_round((mem_size / UNIV_PAGE_SIZE) *

(sizeof *block) + (UNIV_PAGE_SIZE – 1), UNIV_PAGE_SIZE);

os0proc.cc::os_men_alloc_large(mem_size);                                     流程2.3

frame = (bytes *) ut_align(chuck->mem, UNIV_PAGE_SIZE); 流程2.4

buf_block_init(buf_pool, block, frame);                                        流程2.6

UT_LIST_ADD_LAST(buf_pool->free);                                           流程2.7

buf_pool->page_hash = hash_create(2 * buf_pool->curr_size);     流程2.8

buf_pool_set_sizes();

buf_LRU_old_ratio_update(100 * 3/ 8, FALSE);                                            流程3

buf0lru.cc::buf_LRU_old_ratio_update_instance();

btr_search_sys_create();

// 至此,系统启动时,buf pool的初始化完成

 

推荐阅读的关联文章:
MySQL数据库分布式事务XA的实现原理分析

MySQL数据库InnoDB存储引擎Log漫游(1)
MySQL数据库InnoDB存储引擎Log漫游(2)
MySQL数据库InnoDB存储引擎Log漫游(3)

MySQL数据库InnoDB存储引擎原生Checkpoint策略及各版本优化详解

MySQL5.5数据库innodb_change_buffering怪异问题分析

MySQL数据库InnoDB存储引擎中的锁机制

MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析

MySQL数据库分布式事务XA的实现原理分析

MySQL数据库分布式事务XA的实现原理分析

MySQL数据库分布式事务XA优缺点与改进方案

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>