mysql中free 链表

292 阅读3分钟

mysql 中 free 链表是个什么东西?

我们知道 mysql 中有一个非常重要的内存组件,就是缓冲池(Buffer Pool)。它里面缓存了很多的数据,使得我们在查询和修改数据的时候可以基于内存来操作,极大地提高了执行效率。

当然,缓存池毕竟还是内存,如果机器宕机,内存里的数据就丢失了,mysql 为了保证数据不丢失,于是引入了 redo log,undo log,bin log等一系列日志,为的就是不丢失数据,我们看下图。

图片.png

数据库启动的时候,是如何初始化 Buffer Pool 的呢?

其实数据库一启动,就会按照比你设置的Buffer Pool大小再大一点的大小(因为 Buffer Pool 里面还要放描述数据嘛)去操作系统申请一块内存区域。然后数据库就会按照默认的缓存页大小(一般是16kb)以及对应的的描述数据,划分出来一个一个的缓存页和一个一个的他们对应的描述数据。

那么问题来了。 因为数据库刚刚启动, Buffer Pool 中的缓存页都是空的,里面并没有存放数据,只有当我们要对数据执行增删改查的操作的时候,才会把数据对应的页从磁盘文件里读取出来,放入Buffer Pool中的缓存页中。 然后呢数据库运行一段时间后,肯定有些缓存页里面,放了数据了,如果此时又想将磁盘里的数据读出来放到缓存页里,那么我们怎么知道哪些缓存页是空闲的呢?难道随便找一个缓存页就放数据吗?那么如果该缓存页里面有数据的话,你这么一放,不就全覆盖了吗? 这个时候呢?就轮到我们今天的主角,free 链表出场啦!

free 链表

free链表,是一个双向链表,那它里面存放的是什么呢?实际上这个free链表里的每个节点就是一个空闲的缓存页的描述数据块的地址,也就是说,free 链表里面存放的描述数据块对应的缓存页全是空闲的。

那么我们就从刚开始数据库启动开始说起,此时所有的缓存页都是空闲的,所以此时所有缓存页的描述数据块,都会被放入这个free链表中。

其实free 链表本身就是由Buffer Pool里的描述数据块组成的,也就是说每个描述数据块里都有两个指针,一个是free_pre,一个是free_next,分别指向自己的上一个free链表的节点,以及下一个free链表的节点。

free链表中只有一个基础节点是不属于Buffer Pool的,它里面就存放了free链表的头节点的地址,尾节点的地址,还有free链表里当前有多少个节点。

图片.png

总结

解决MySQL innodb 读取数据的时候 把数据页放入到buffer pool 的某个缓存页中 就是要知道那个是空闲的