什么是数据库的“缓存池”?

Buffer Pool 概述Buffer Pool 是什么?从字面上看是缓存池的意思,没错,它其实也就是缓存池的意思 。它是 MySQL 当中至关重要的一个组件,可以这么说,MySQL的所有的增删改的操作都是在 Buffer Pool 中执行的 。
但是数据不是在磁盘中的吗?怎么会和缓存池又有什么关系呢?那是因为如果 MySQL的操作都在磁盘中进行,那很显然效率是很低的,效率为什么低?因为数据库要从磁盘中拿数据啊,那肯定就需要IO啊,并且数据库并不知道它将要查找的数据是磁盘的哪个位置,所以这就需要进行随机IO,那这个性能简直就别玩了 。所以 MySQL对数据的操作都是在内存中进行的,也就是在 Buffer Pool 这个内存组件中 。
实际上他就好比是 redis,因为 Redis 是一个内存是数据库,他的操作就都是在内存中进行的,并且会有一定的策略将其持久化到磁盘中 。那 Buffer Pool 的内存结构具体是什么样子的,那么多的增删改操作难道数据要一直在内存中吗?既然说类似 redis 缓存,那是不是也像 redis 一样也有一定的淘汰策略呢?
本篇文章,会详细的介绍 Buffer Pool 的内存结构,让大家彻底明白这里面的每一步执行流程 。我们先看一下 MySQL从加载磁盘文件到完成提交一个事务的整个流程 。我们先来看一个总体的流程图,从数据在磁盘中被加载到缓存池中,然后经过一些列的操作最终又被刷入到磁盘的一个过程,都经历了哪些事情,这个图不明白没有关系,因为本文重点是 Buffer Pool 这个整体的流程就是让大家稍微有个印象 。

什么是数据库的“缓存池”?

文章插图
 
2、Buffer Pool 有多大Buffer Pool 是 InnoDB 中的一块内存区域,他一定是有自己的大小的,且大小默认是 128M,不过这个容量似乎有点小了,大家的自己的生产环境可以根据实际的内存大小进行调整,参数为:innodb_buffer_pool_size=2147483648 单位是字节,
# 查看和调整innodb_buffer_pool_size1. 查看@@innodb_buffer_pool_size大小,单位字节SELECT @@innodb_buffer_pool_size/1024/1024/1024; #字节转为G2. 在线调整InnoDB缓冲池大小,如果不设置,默认为128Mset global innodb_buffer_pool_size = 4227858432; ##单位字节他在 InnoDB 中的整体结构大概是这样子的
什么是数据库的“缓存池”?

文章插图
 
3、数据页刚刚介绍到 MySQL在执行增删改的时候数据是会被加载到 Buffer Pool 中的,既然这样数据是怎么被加载进来的,是一条一条还是说是以其他的形式呢 。我们操作的数据都是以表 + 行的方式,而表 + 行仅仅是逻辑上的概念,MySQL并不会像我们一样去操作行数据,而是抽象出来一个一个的数据页概念,每个数据页的大小默认是 16KB,这些参数都是可以调整的 。但是建议使用默认的就好,毕竟 MySQL能做到极致的都已经做了 。每个数据页存放着多条的数据,MySQL在执行增删改首先会定位到这条数据所在数据页,然后会将数据所在的数据页加载到 Buffer Pool 中 。
什么是数据库的“缓存池”?

文章插图
 
4、缓存页当数据页被加载到缓冲池中后,Buffer Pool 中也有叫缓存页的概念与其一一对应,大小同样是 16KB,但是 MySQL还为每个缓存也开辟额外的一些空间,用来描述对应的缓存页的一些信息,例如:数据页所属的表空间,数据页号,这些描述数据块的大小大概是缓存页的15%左右(约800B) 。
#缓存页是什么时候被创建的?当 MSql 启动的时候,就会初始化 Buffer Pool,这个时候 MySQL 会根据系统中设置的 innodb_buffer_pool_size 大小去内存中申请一块连续的内存空间,实际上在这个内存区域比配置的值稍微大一些,因为【描述数据】也是占用一定的内存空间的,当在内存区域申请完毕之后,MySql 会根据默认的缓存页的大小(16KB)和对应`缓存页*15%`大小(800B左右)的数据描述的大小,将内存区域划分为一个个的缓存页和对应的描述数据
什么是数据库的“缓存池”?

文章插图
 
5、Free链表上面是说了每个数据页会被加载到一个缓存页中,但是加载的时候 MySQL是如何知道那个缓存页有数据,那个缓存页没有数据呢?换句话说,MySQL是怎么区分哪些缓存页是空闲的状态,是可以用来存放数据页的 。
为了解决这个问题,MySQL 为 Buffer Pool 设计了一个双向链表— free链表,这个 free 链表的作用就是用来保存空闲缓存页的描述块(这句话这么说其实不严谨,换句话:每个空闲缓存页的描述数据组成一个双向链表,这个链表就是free链表) 。之所以说free链表的作用就是用来保存空闲缓存页的描述数据是为了先让大家明白 free 链表的作用,另外 free 链表还会有一个基础节点,他会引用该链表的头结点和尾结点,还会记录节点的个数(也就是可用的空闲的缓存页的个数) 。


推荐阅读