MySQL 之 Buffer Pool

一、innoDB设计缓冲池目的

        避免频繁访问磁盘,提高数据库性能。(作用与引用Cache三级缓存类似。)

二、缓冲池工作模式

        读取数据:当Buffer Pool存在目标数据,就直接返回给客户端,没有再磁盘取数据。

        修改数据:修改Buffer Pool中数据的页,并将其设为脏页,最后后台线程将脏页写入磁盘。

三、缓冲池基本概念

申请时间及大小

        MySQL启动后向OS申请一片连续内存空间。默认128MB。

        磁盘和内存交互基本单位:页。页的大小:16KB。

结构

        主要为:全局内存(Global buffer)线程内存(Thread buffer) 两大部分。

全局内存:缓冲池里面有数据缓存页、索引缓存页、锁信息页、插入缓存页等等。                                                  此外还有重做日志缓存、额外的内存池。
线程内存:Master Thread、IO Thread、Purage Thread、Page Cleaner Thread。

MySQL 之 Buffer Pool_第1张图片

缓存页与控制块

innoDB为每个缓存页创建一个控制块,控制块信息包括「缓存页的表空间、页号、缓存页地址、链表节点」

MySQL 之 Buffer Pool_第2张图片

碎片空间产生原因

Buffer Pool大小固定,每个缓存页对应一个控制块 大小固定。如果设置大小不是刚好的,就会产生多余的内存空间,也就是碎片空间。

从磁盘查询一条记录,是只缓冲一条记录吗?

磁盘与内存交互基本单位是页。而且索引也只能定位到记录属于磁盘中哪个页,

将页缓冲到Buffer Pool中后再通过页目录定位到具体的哪条记录。

Buffer Poll管理

空闲页管理

当从磁盘读取数据缓存到 Buffer Poll的空闲缓存页,需要快速找到哪些缓存页是空闲的!

方法:创建Free链表,将空闲页的控制块作为节点,加入到Free链表。

缓存页空闲,则将其控制块加入到Free链表;缓存页存储数据了,则将其控制块移除Free链表。

脏页管理

当后台线程要将脏页写入到磁盘,需要快速找到哪些缓存页 是脏页!

方法:创建Flush链表,将脏页的控制块作为节点,加入到Flush链表。

后台线程直接遍历 Flush 链表,将脏页写入到磁盘。

提高磁盘命中率方法

LRU(Least recently used)算法

(根据程序局部性原理生成)

  • 当访问的页在 Buffer Pool 里,就直接把该页对应的 LRU 链表节点移动到链表的头部。
  • 当访问的页不在 Buffer Pool 里,除了要把磁盘中的页放入到 LRU 链表的头部,还要淘汰 LRU 链表末尾的节点。

弊端:预读失效 ;Buffer Poll污染

预读机制

据程序空间局部性原理,在加载数据页时提前将其相邻数据页加载,目的减少磁盘IO;

预读失效:不会被访问的预读页却占用了 LRU 链表前排的位置,而末尾淘汰的页,可能是频繁访问的页,这样就大大降低了缓存命中率。

解决方法:LRU 划分了2 个区域:old 区域 和 young 区域预读的页就只需要加入到 old 区域的头部,当页被真正访问的时候,才将页插入 young 区域的头部。

young区域 存储热数据;old区域 存储冷数据;

MySQL 之 Buffer Pool_第3张图片

Buffer Poll污染

Buffer Poll污染:当某个SQL语句扫描大量数据,将Buffer Poll里数据页全替换,淘汰大量热数据。再次访问时产生大量磁盘IO,使MySQL性能急剧下降。

解决方法:进入到 young 区域条件增加了一个停留在 old 区域的时间判断

同时满足「被访问」与「在 old 区域停留时间超过 1 秒」两个条件,才会被插入到 young 区域头部

脏页写入磁盘时机

        如果每次修改数据均刷入磁盘,性能会很低。因此在一定时机,批量刷盘。

MySQL宕机防止脏页丢失策略

        Write Ahead Log策略。也就是先写日志,再写入磁盘。通过redo Log日志,让MySQL有崩溃恢复能力。

触发脏页刷新时机

  • 当 redo log 日志满了的情况下,会主动触发脏页刷新到磁盘;
  • Buffer Pool 空间不足时,需要将一部分数据页淘汰掉,如果淘汰的是脏页,需要先将脏页同步到磁盘;
  • MySQL 认为空闲时,后台线程会定期将适量的脏页刷入到磁盘;
  • MySQL 正常关闭之前,会把所有的脏页刷入到磁盘;

你可能感兴趣的:(数据库,mysql,数据库)