Mysql的BufferPool与Free、Flush、Lru链表

  • 1. BufferPool
  • 2. 管理BufferPool的链表
    • (1) Free List
    • (2) Flush List
    • (3) Lru List

1. BufferPool

操作系统,会有缓冲池 (buffer pool) 机制,避免每次访问磁盘,以加速数据的访问

MySQL 作为一个存储系统,同样具有缓冲池 (buffer pool) 机制,以避免每次查询数据都进行磁盘 IO
(磁盘读写是按页读取,一次至少读一页数据,一般是4K)

BufferPool一般存储的是经常访问的数据,而持久化的数据会放入磁盘

BufferPool是内存上的一块区域,可以看作是一个数组,因为C语言在开辟内存空间的时候,是一个数组,BufferPool默认大小是128M

通过以下例子和描述来理解BufferPool的运行机制:

例如MySql数据库发起一个查询请求 select * from test_db where id = 9

该查询请求会经历以下步骤:

① 先从BufferPool中查找,没有的话就到磁盘中去查找

② 当在查找到了之后,如果是在磁盘上,则会将查询到的结果从磁盘中复制该页的数据到Buffer Pool中

Mysql的BufferPool与Free、Flush、Lru链表_第1张图片
当第二次还有相同请求发起的时候 select * from test_db where id = 9,就会在BufferPool中读取到数据

2. 管理BufferPool的链表

在Innodb中,有free、Flush、Lru三种链表管理,所以可以描述为Free、Flush、Lru链表是为了管理BufferPool而存在的

(1) Free List

当sql语句执行多了之后,比如update语句执行多了,会出现BufferPool中间有的页数据持久化移动到了硬盘,这时会在数组中间出现许多空闲页

这是因为BufferPool因为是以数组存储的方式,所以才会出现许多中间空闲的页

那么这时会有一种叫做Free List链表管理空闲页

Free链表由基节点和子节点组成,子节点有控制块,控制块即是空闲页中的一个对象,利用它用来定位空闲页

在后续要再从硬盘读取数据copy到BufferPool的时候,会直接到Free链表去找空闲页的位置
Mysql的BufferPool与Free、Flush、Lru链表_第2张图片

(2) Flush List

当BufferPool中的页发生改变时,会变成脏页脏页会添加到Flush链表上去控制
Mysql的BufferPool与Free、Flush、Lru链表_第3张图片
MySql数据库后台会有一个线程,专门定时去flush链表查找脏页,从而需要修改保存数据的时候,就直接将该脏页持久化到硬盘上

(3) Lru List

Lru(最近最近未使用)

当BufferPool满了之后,会将不常用的页给淘汰掉,这种淘汰机制会有一个链表去控制,这种链表叫 Lru链表

最原始的Lru链表如下
在这里插入图片描述
Lru链表的淘汰机制

① 当有新数据从硬盘读取到BufferPool的时候,会插入到Lru链表的头部,表示这是最近最新用到的数据

② 当BufferPool中有再次使用到的数据页时,页会更新到lur链表的头部

③ 那么这时 :Lru 链表最后一个数据就代表是最久没用到过的数据,淘汰的时候就会删除尾部的节点和对应的页来实现淘汰机制

最原始的 Lur链表 的缺点:

当查询的数据量比较大的时候,比如说全表扫描,每次都会替换掉BufferPool中的页,如果过大可能是全部都替换,很多热点数据页(经常访问的数据)也会被淘汰,当然也会很影响性能

为了解决这个问题,Innodb将Lru链表分成了5/8的热数据区域和3/8的冷数据区域,变成了升级后的Lru链表,如下图
在这里插入图片描述
新的 Lru 淘汰机制(专业词汇是称为页面置换算法)

当有新的数据页要从磁盘读取出来存储在BufferPool时,会将冷数据区域最后一个淘汰,并将该页存储在冷数据区域的头节点
Mysql的BufferPool与Free、Flush、Lru链表_第4张图片
从冷数据区域移动到热数据区域的原则:

如果对于冷数据区域一页数据的两次请求时间间隔<1秒,则不会移动
因为InnoDB会认为是在做全表扫描

如果对于冷数据区域一页数据的两次请求时间间隔>1秒,则会移动到热数据区域
因为这时InnoDB会认为这是客户端频繁请求的数据,所以放入热数据区域

你可能感兴趣的:(java)