前言
最近在学习mysql数据库InnoDB引擎的相关知识,在学习的过程中做了一些摘抄和笔记,同时也有一些自己的理解,希望能分享给大家,共同学习,欢迎指正
InnoDB源码文件
先来看一些相关文件及其说明
文件名 | 说明 |
---|---|
dyn0dyn.* | 动态数组的实现 |
fut0fut.* | 基于文件的工具集,实现了基于磁盘地址而不是内存地址的双链表 |
fut0lst.* | 操作 |
ha0ha.* | 用于哈希索引系统的哈希表实现 |
hash0hash.* | 简单哈希表实现,用于fil、buf和recv等模块中 |
mem0. | 内存管理系统,包括内存池的实现 |
ut0byte.* | 字节操作实现 |
ut0dbg.c | debug工具 |
ut0mem.* | 内存管理基元,内存块实现 |
ut0rnd.* | 随机值和哈希值操作实现 |
ut0ut.* | 其它常用操作,包括时间、打印、对数和指数操作 |
ut0sort.h | 标准排序算法的宏定义,基于合并排序 |
ut0lst.h | 双向线性链表实现 |
内存管理
InnoDB存储引擎采用内存堆的方式来进行内存对象的管理(而不是直接使用malloc和free),其优点是可以一次性分配大块的内存,而不是按需分配。这样的分配方式可以将多次的内存分配合并为单次进行,之后的内存请求救可以在InnoDB引擎内部进行,从而减少了频繁调用函数malloc和free进行的时间与潜在的性能开销。
此外,InnoDB存储引擎还允许从缓冲池中分配内存来建立内存堆,这样可以更快的请求整个内存页(通常为16K)。这种分配方法称为缓冲池分配

在这,我联想到之前看到过在php的内核中,内存管理也是采取这样的方式,因为不管是php还是mysql都要经常的申请和释放内存,而只有操作系统才能使用malloc和free操作内存,普通的应用程序是无法直接对内存进行访问的,需要向操作系统申请,向操作系统申请会引发系统调用,在系统调用时,cpu要从用户态切换到内核态,而这个切换的开销是比较大的,如果频繁切换则会有很大性能开销。所以,在对内存有频繁操作的应用程序中,通常每次申请一大块内存来自己维护,同样的在这些内存使用完之后也不立刻归还给操作系统,而是自己留着以备下次使用
内存块的数据结构
内存堆相当于一个栈,通过不断的增加内存块对象来增长空间,
InnoDB使用mem_block_t来表示内存堆中每次从操作系统或者缓冲池中分配的内存块。
/innobase/include/mem0mem.h line:43
1 | /* A block of a memory heap consists of the info structure |
mem_block_info_t的数据结构如下:
1 | ### /innobase/include/mem0mem.h line:371 |
UT_LIST_BASE_NODE_T ### /innobase/include/ut0lst.h line:75
1 | This macro expands to the unnamed type definition of a struct which acts |
可以看到,有两个指针指向链表头和链表尾部,count存储节点个数
UT_LIST_NODE_T在 ### /innobase/include/ut0lst.h line:75
1 | template <typename TYPE> |
可以看到有两个指针指向前一个和后一个结点

InnoDB 存储引擎定义了三种内存堆类型:
/innobase/include/mem0mem.h line:52
1 |
内存堆的创建是由函数mem_heap_create_func完成
/innobase/include/mem0mem.ic line:431
1 | /*****************************************************************//** |
从上面代码中可以看到mem_heap_create_func主要是调用mem_heap_create_block函数实现内存块的创建的
/innobase/include/mem0mem.ic line:32
1 | # define mem_heap_create_block(heap, n, type, file_name, line) \ |
再来追mem_heap_create_block_func函数
/innobase/mem/mem0mem.cc line:296
1 | /***************************************************************//** |
这个就是最终的创建内存块的函数,主要是对mem_block_t结构的一些赋值操作