MySQL内核——学习笔记01

参考:《MYSQL内核:INNODB存储引擎 卷1》第二章

此文只是对文中的知识点做了一个整理。源码版本:3.23.49

两个特殊文件

Iniv

主要功能:根据操作系统版本定义inline的关键字

iniv文件位置

D:\mysql-3.23.49\innobase\include

ic文件

功能:内联函数的实现

位置:D:\mysql-3.23.49\innobase\include\xx0xx.ic

如:

Dy0dy.h中:

用source insight是找不到这个函数的实现的,

看开头include里的这几个文件也找不到dyn_array_create的实现

找一下D:\mysql-3.23.49\innobase\include\dyn0dyn.ic

果然有:

内存块

mem_block_info_struct

mem_block_info_struct的结构有点绕,

先看base部分,原始的两段结构体定义:

下面来一步步拆解,

先把type替换掉,

再回到第一个结构体:

再根据一、二整合:

Mem_block_info_struct里的list/mem_block_list也同理,做个替换

最终的字段:

Iniv文件中的UNIV_INLINE语法

上面相当与关键字替换,依据运行的平台,把红色的替换成蓝色的。

实际用的时候:

—–mem0mem.h—–

UNIV_INLINE

mem_heap_t*

mem_heap_create_func( )

等同于:

Extern inline

mem_heap_t*

mem_heap_create_func( )

内存堆

内存堆的结构与类型

P10

这个组织结构从mem_block_info_struct的定义可以看出。

内存对的类型(按找申请来源来划分的)

另外,在mem0mem.c开头的注释也有一些说明:

1 MEM_HEAP_DYNAMIC从c编译器获取,也就是直接从系统内存动态分配;

2 MEM_HEAP_BUFFER从缓冲池分配内存。

内存堆里分配的内存空间大小如何确定

P11

从以下可以看出来

缓冲池

Srv_mem_pool_size

P12这段话的理解:

为什么通用内存池大小是srv_mem_pool_size指定的?

先找到谁调用了mem_pool_create函数:

Mem0dbg.c

Mem_comm_pool是一个对象,即通用内存池,它的介绍看P11这段:

这个初始话操作是在mem_init函数里进行的,那是谁调用mem_init呢:

Srv0srv.c

再看这个文件的上面,可以关联起来了:

Mem_comm_pool的赋值

P11:

先找到mem_comm_pool:

查看mem_pool_create函数定义:

这是一个宏:

Ut_LIST_BASE_NODE_T

Mem0pool.c

  1. Mem_area_t实际上是一个别名,别名类型为结构:

  1. 因此,mem_pool_struct可以写作:

  1. 再看mem_area_struct:

  1. 再看mem_area_t:

同样是别名,

5. 再看UT_LIST_NODE:

  1. 所以根据345,mem_area_struct就是:

  1. 再看mem_pool_struct的UT_LIST_BASE_NODE_T:

  1. 根据267整理得mem_pool_struct的结构:

再结合这张图来看:

可以得到以下关系:

Mem_pool和mem_area之间的组织关系通过mem_pool_structure.free_list来维护。

通用内存池的用途规划

在Mem0pool.c的一段注释,可以帮助理解为什么要这要设计:

/* We would like to use also the buffer frames to allocate memory. This

would be desirable, because then the memory consumption of the database

would be fixed, and we might even lock the buffer pool to the main memory.

The problem here is that the buffer management routines can themselves call

memory allocation, while the buffer pool mutex is reserved.

The main components of the memory consumption are:

1. buffer pool,

2. parsed and optimized SQL statements,

3. data dictionary cache,

4. log buffer,

5. locks for each transaction,

6. hash table for the adaptive index,

7. state and buffers for each SQL query currently being executed,

8. session for each user, and

9. stack for each OS thread.

(以下省略)

 伙伴系统算法

伙伴系统原理

伙伴系统具体实现

从代码里整理了一张图:目前只能看懂mem_area_get_buddy这个函数,至于怎么调用它,然后分配内存的看不懂了。

其中,

ut_a ut_ad 类似于C语言中 assert 的断言功能,当()中的表达式不为真则mysql主程序直接退出

仅是判断函数或者变量是否是预期的值,仅仅是判断的功能,不会对流程起任何作用,仅用来保护流程

哈希表

哈希表的定义和创建

创建哈希表的方法:

总结如下:

插入到哈希表中的方法

参考了这个博客 <https://blog.csdn.net/fly43108622/article/details/91046240>

文件位置:Ha0ha.c

整理流程如下

定义heap的过程:

插入第一个值的过程:

Code line 133以后:注意这里的prev_node和node都是局部变量,在函数执行完毕后会被回收。

这段的意思是,如果cell值一样,fold值也一样,那么它的实际data值也必定一样,所要做的只是更新一下data域。

插入第二个值的过程:

Code line 133以后:

ha_node_t

所以会有:

ha_node_t* node111

ha_node_t* top_node111

即定义一个变量node111,然后定义一个指针ha_node_t*指向这个变量的地址。

动态数组

dyn_block_struct

参考到这篇文章<https://blog.csdn.net/whyangwanfu/article/details/2924821>

  1. 定义:

  1. 标红的两个结构

  1. 根据1和2整理得:

  1. 执行dyn_array_create

dyn_array_add_block

1.

2.上面标红处的结构为:

  1. 依据1和2:

  1. 关注这段:

  1. 根据4和5,整理:

插入第一个值后的总结如下:

合并排序

owhigh分别对应在数组中元素所在的位置。如数组中有10个元素,从0开始到9,则low就是0high就是10,注意:

and the low (LOW), inclusive, and high (HIGH), noninclusive,

limits for the sort interval as arguments.

/***********************************************************************

This macro expands to the body of a standard sort function.

The sort function uses mergesort and must be defined separately

for each type of array.

Also the comparison function has to be defined individually

for each array cell type. SORT_FUN is the sort function name.

The function takes the array to be sorted (ARR),

the array of auxiliary space (AUX_ARR) of same size,

and the low (LOW), inclusive, and high (HIGH), noninclusive,

limits for the sort interval as arguments.

CMP_FUN is the comparison function name. It takes as arguments

two elements from the array and returns 1, if the first is bigger,

0 if equal, and -1 if the second bigger. For an eaxmaple of use

see test program in tsut.c. */

auxiliary space 辅助空间

谁来调用它:

Ut_ulint_cmp的定义:

根据上面的信息整理替换:

推演了一部分实现过程:

输入数组aux[6,7,1,5,3,4,2,8]

发表评论

电子邮件地址不会被公开。