IT技术博客大学习 共学习 共进步

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

MySQLOPS 数据库与运维自动化技术分享 2012-05-28 12:35:52 浏览 2,542 次

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的初始化完成

建议继续学习

  1. Buffer和cache的区别是什么? (阅读 7,841)
  2. Linux操作系统中内存buffer和cache的区别 (阅读 6,341)
  3. 快速预热Innodb Buffer Pool的方法 (阅读 4,983)
  4. MySQL数据库InnoDB存储引擎 Buffer pool LRU List Flush策略详解 (阅读 4,923)
  5. InnoDB之Dirty Page、Redo log (阅读 4,481)
  6. MySQL数据库InnoDB存储引擎 Insert Buffer实现机制详解 (阅读 4,382)
  7. 小心grep 的buffer (阅读 4,103)
  8. grep 命令的buffer选项 (阅读 3,963)
  9. HBase如何合理设置客户端Write Buffer (阅读 3,720)
  10. 浅谈数据库系统中的cache (阅读 3,103)