MYSQL专题(四):buffer pool

Buffer Pool

  • 我们对数据库执行增删改操作的时候,不可能直接更新磁盘上的数据,如果直接对磁盘进行随机读写操作,那速度是相当慢,随便一个大磁盘文件的随机读写操作,都有可能要几百毫秒。
  • 我们在对数据库执行增删改操作的时候,实际上主要都是针对内存里的Buffer Pool的数据进行的,也就是你实际上主要是对数据库的内存里的数据结构进行增删改操作。
    MYSQL专题(四):buffer pool
Buffer Pool的大小
  • Buffer Pool默认大小是128M,
  • innodb_buffer_pool_size = xxxxx,可以设置大小
buffer pool的结构
数据页:mysql抽象出来的数据单元
  • 数据库的核心数据模型:表+字段+行
  • mysql对数据抽象出来了一个数据页的概念,他是把很多行数据放在一个数据页里面,也就是说我们的磁盘文件就是会有很多的数据页,每一页数据放了很多行数据。

MYSQL专题(四):buffer pool
如果我们要更新一行数据,数据库会找到这行数据所在的数据页,然后把磁盘文件里把这行数据所在的数据页直接给加载到Buffer Pool里面去了;也就是说Buffer Pool中存放的是一个个数据页
MYSQL专题(四):buffer pool

  • 对于每一个缓存页,他实际上都会有一个描述信息,这个描述信息大体可以认为是用来描述这个缓存页的,他包含了:这个数据页所属的表空间,数据页的编号,这个缓存页在buffer Pool中的地址以及别的一些二数据
  • 每个缓存页都会对应一个描述信息,这个描述信息本身也是一块数据,在buffer Pool中,每个缓存页的描述信息放在最前面,每个缓存页放在后面

MYSQL专题(四):buffer pool

  • buffer pool中的描述数据(控制数据)大概相当于缓存页大小的百分之5左右,
初始化buffer pool
  • 数据库一启动,就会按照用户设置的buffer pool的大小,稍微加大一点,然后去找操作系统申请一块内存区域,作为buffer pool的内存区域。
  • 内存申请完毕之后,数据库就会按照默认的缓存页的16KB的大小以及对应的800个字节左右的描述数据的大小,在buffer pool中划分出一个个缓存页和对应的描述信息
如何知道缓存页是空闲的:free链表
  • 数据库会为buffer pool设计一个free链表,他是一个双向链表数据结构,这个free链表里,每个节点就是一个空闲的缓存页的描述数据块地址;也就是如果一个缓存页是空闲的,那么他的描述数据块就会被放如这个free链表中

  • MYSQL专题(四):buffer pool

  • 基础节点:存放free链表的头节点地址,尾节点地址,还有free链表里当前有多少个节点。

  • 每次把数据放到缓存页中,就把这个节点在free链表删除

如何知道数据页有没有被缓存
  • 数据库还会有一个hash表数据结构,他会用表空间号+数据页号作为key,然后缓存页的地址作为value
  • 然后每次读取一个缓存页到缓存之后,都会在这个hash表中写入一个key-value对
    MYSQL专题(四):buffer pool
flush链表

我们对缓存页增删改查后,缓存页上的数据就变成了脏数据
MYSQL专题(四):buffer pool

  • flush链表是存储被修改过的缓存页,用来记录脏页,后面好方便刷到磁盘中
    MYSQL专题(四):buffer pool
buffer Pool CRUD的流程
  • 查询数据和修改数据,都要先把数据页加载到缓存页中
    MYSQL专题(四):buffer pool
  • 一直加载的话 缓存页就会不够
    MYSQL专题(四):buffer pool
  • 要淘汰一些缓存数据—根据淘汰策略、
    MYSQL专题(四):buffer pool
    淘汰策略要考虑缓存命中率的问题
引入LRU链表来判断哪些缓存页不常用

MYSQL专题(四):buffer pool
MYSQL专题(四):buffer pool

  • 每次没有空闲的缓存页的时候,就找出URL链表的尾部,把他刷到磁盘中去,腾出空闲空间。