13 从磁盘读取数据页到Buffer Pool的时候,free链表有什么用?
1.数据库启动的时候,是如何初始化Buffer Pool的?
数据库一启动就会按照你设置的Buffer Pool的大小,在操作系统里分配一块内存区域,作为Buffer Pool内存区域
当内存区域申请完毕之后,数据库就会按照默认的缓存页16kB的大小以及对应的800个字节左右的描述数据的大小,在Buffer Pool里划分出来一个一个的缓存页和对应的描述数据
只不过现在的缓存页是空的,当我们进行数据库的增删改查时,才会把对应的页从磁盘文件里读取出来,放到Buffer Pool中缓存页中。
2.我们怎么知道哪些缓存页是空闲的?
默认情况下,数据页和缓存页是一一对应的,都是16kb,一个数据页对应一个缓存页
所以我们必须知道哪些缓存页是空闲的,所以数据库会为Buffer Pool 设计一个free 链表,他是一个双向的链表,每个链表里存的是空闲的缓存页的描述数据块的地址,也就是说只要你一个缓存页是空闲的,这个空闲的缓存页的描述数据块的地址就会存在free链表里,刚开始数据都是空的,描述数据块的地址都会被存放在free链表中
3.如何将磁盘上的数据页读取到Buffer Pool 的缓存页中?
首先从free链表获取一个描述数据块。然后就可以获取到对应的这个描述数据块的缓存页
接着我们就可以把磁盘上的数据页读取到对应的缓存里去,同时把相关的一些描述数据写入到缓存页的描述数据里,比如这个数据页所属的表空间之类的信息,最后把那个描述数据块从free链表去除
4.你怎么知道数据页有没有被缓存?
我们在执行增删改查的时候,如果没有被缓存,就走上边的逻辑,先从free链表中找到一个空闲的缓存页,从磁盘读取数据页写入缓存页,写入描述数据,从free链表中移除这个描述数据块
数据库其实还有一个哈希表数据结构,他会用表空间号+数据页号,作为一个key,然后缓存页地址作为value。
当你要使用一个数据页的时候,通过“表空间号+数据页”作为key去哈希表去查一下,查到就说明数据页已经被缓存了,查不到就去读取数据页