【大白话系列】MySQL 学习总结 之 缓冲池(Buffer Pool) 的设计原理和管理机制

发表于 4年以前  | 总阅读数:669 次

一、缓冲池(Buffer Pool)的地位

在《MySQL 学习总结 之 InnoDB 存储引擎的架构设计》中,我们就讲到,缓冲池是 InnoDB 存储引擎中最重要的组件。因为为了提高 MySQL 的并发性能,使用到的数据都会缓存在缓冲池中,然后所有的增删改查操作都将在缓冲池中执行。

通过这种方式,保证每个更新请求,尽量就是只更新内存,然后往磁盘顺序写日志文件

更新内存的性能是极高的,然后顺序写磁盘上的日志文件的性能也是比较高的,因为顺序写磁盘文件,他的性能要远高于随机读写磁盘文件。

正因为缓冲池的重要性,所以我们必须比较深入地去理解和研究其中的原理和机制。当然了,我这里还是比较大白话的介绍缓冲池这个组件的原理,比较适合大家比较整体和从宏观上去了解,如果需要更加深入的,建议大家去看 MySQL 的官方文档,或者是相关技术书籍。

二、 Buffer Pool 的大小

缓冲池(Buffer Pool)的默认大小为 128M,可通过 innodb_buffer_pool_size 参数来配置。

三、Buffer Pool 的结构

当 SQL 执行时,用到的相关表的数据行,会将这些数据行都缓存到 Buffer Pool 中。

但是我们可以想象一下,如果像上面的机制那么简单,那么如果是分页的话,不断地查询就要不断地将磁盘文件中数据页的数据缓存到 <Buffer Pool 中了,那么这时候缓存池这个机制就显得没什么用了,每次查询还是会有一次或者多次的磁盘IO。

但是怎么缓存呢?

1、数据页概念

我们先了解一下数据页这个概念。它是 MySQL 抽象出来的数据单位,磁盘文件中就是存放了很多数据页,每个数据页里存放了很多行数据。

默认情况下,数据页的大小是 16kb。

对应的,在 Buffer Pool 中,也是以数据页为数据单位,存放着很多数据。但是我们通常叫做缓存页,因为 Buffer Pool 毕竟是一个缓冲池,并且里面的数据都是从磁盘文件中缓存到内存中。

默认情况下缓存页的大小也是 16kb,因为它和磁盘文件中数据页是一一对应的。

所以,缓冲池和磁盘之间的数据交换的单位是数据页,包括从磁盘中读取数据到缓冲池和缓冲池中数据刷回磁盘中,如图所示:

2、怎么识别数据在哪个缓存页中?

到此,我们都知道 Buffer Pool 中是用缓存页来缓存数据的,但是我们怎么知道缓存页对应着哪个表,对应着哪个数据页呢?

所以每个缓存页都会对应着一个描述数据块,里面包含数据页所属的表空间、数据页的编号,缓存页在 Buffer Pool 中的地址等等。

描述数据块本身也是一块数据,它的大小大概是缓存页大小的5%左右,大概800个字节左右的大小。

描述如图所示:

四、Buffer Pool 的初始化


到此,我们都知道了,Buffer Pool 是缓存数据的数据单位为缓存页,利用描述数据块来标识缓存页。

那么,MySQL 启动时,是如何初始化 Buffer Pool 的呢?

1、MySQL 启动时,会根据参数 innodb_buffer_pool_size 的值来为 Buffer Pool 分配内存区域。

2、然后会按照缓存页的默认大小 16k 以及对应的描述数据块的 800个字节 左右大小,在 Buffer Pool 中划分中一个个的缓存页和一个个的描述数据库块。

3、注意,此时的缓存页和描述数据块都是空的,毕竟才刚启动 MySQL 呢。

五、Free 链表记录空闲缓存页

上面我们了解了 Buffer Pool 在 MySQL 启动时是如何初始化的。当 MySQL 启动后,会不断地有 SQL 请求进来,此时空闲的缓存页就会不断地被使用。

那么, Buffer Pool 怎么知道哪些缓存页是空闲的呢?

1、Free 链表的使用原理

free 链表,它是一个双向链表,链表的每个节点就是一个个空闲的缓存页对应的描述数据块。

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

通过 Buffer Pool 中的描述数据块的 free_pre 和 free_next 两个指针,就可以把所有的描述数据块串成一个 free 链表。

下面我们可以用伪代码来描述一下 free 链表中描述数据块节点的数据结构:

DescriptionDataBlock{
   block_id = block1;
   free_pre = null;
   free_next = block2;
}

free 链表有一个基础节点**:**他会引用链表的头节点和尾节点,里面还存储了链表中有多少个描述数据块的节点,也就是有多少个空闲的缓存页。

下面我们也用伪代码来描述一下基础节点的数据结构:

FreeListBaseNode{
   start = block01;
   end = block03;  
   count = 2;
}

到此,free 链表就介绍完了。

因为上面我们介绍了 MySQL 启动时 Buffer Pool 的初始流程,所以接下来,我会将结合刚介绍完的 free 链表,讲解一下 SQL 进来时,磁盘数据页读取到 Buffer Pool 的缓存页的过程。但是,我们先要了解一下一个新概念:数据页缓存哈希表,它的 key 是表空间+数据页号,而 value 是对应缓存页的地址

描述如图所示:

2、磁盘数据页读取到 Buffer Pool 的缓存页的过程

1、首先,SQL 进来时,判断数据对应的数据页能否在 数据页缓存哈希表里 找到对应的缓存页。

2、如果找到,将直接在 Buffer Pool 中进行增删改查。

3、如果找不到,则从 free 链表中找到一个空闲的缓存页,然后从磁盘文件中读取对应的数据页的数据到缓存页中,并且将数据页的信息和缓存页的地址写入到对应的描述数据块中,然后修改相关的描述数据块的 free_pre 指针和 free_next 指针,将使用了的描述数据块从 free 链表中移除。记得,还要在数据页缓存哈希表中写入对应的 key-value 对。

4、最后,就能在 Buffer Pool 中进行对表的增删改查了。

六、Flush 链表记录脏缓存页

1、脏页和脏数据

我们都知道 SQL 的增删改查都在 Buffer Pool 中执行,慢慢地,Buffer Pool 中的缓存页因为不断被修改而导致和磁盘文件中的数据不一致了,也就是 Buffer Pool 中会有很多个脏页,脏页里面很多脏数据。

所以,MySQL 会有一条后台线程,定时地将 Buffer Pool 中的脏页刷回到磁盘文件中。

但是,后台线程怎么知道哪些缓存页是脏页呢,不可能将全部的缓存页都往磁盘中刷吧,这会导致 MySQL 暂停很长的一段时间。

2、MySQL 是怎么判断脏页的

我们引入一个和 free 链表类似的 flush 链表。他的本质也是通过缓存页的描述数据块中的两个指针,让修改过的缓存页的描述数据块能串成一个双向链表,这两指针大家可以认为是 flush_pre 指针和 flush_next 指针。

下面我用伪代码来描述一下:

DescriptionDataBlock{
   block_id = block1;
   // free 链表的
   free_pre = null;
   free_next = null;

   // flush 链表的
   flush_pre = null;
   flush_next = block2;
}

flush 链表也有对应的基础节点:也是包含链表的头节点和尾节点,还有就是修改过的缓存页的数量。

FlushListBaseNode{
   start = block1;
   end = block2;
   count = 2;
}

到这里,我们都知道,SQL 的增删改都会使得缓存页变为脏页,此时会修改脏页对应的描述数据块的 flush_pre 指针和 flush_next 指针,使得描述数据块加入到 flush 链表中,之后 MySQL 的后台线程就可以将这个脏页刷回到磁盘中。

描述如图所示:

七、LRU 链表记录缓存页的命中率


1、缓存命中率

我们都知道,当加载磁盘中的数据页到缓存中时,会从 free 链表找到空闲的缓存页,然后将数据加载到缓存页里。

但是缓存页总会有用完的时候,此时需要淘汰一下缓存页,将它刷入磁盘中,然后清空。

那么会选择谁淘汰呢?

那么必定会淘汰缓存命中率低的缓存页。

什么叫缓存命中率低:

  1. 假如你有100次请求,有30次请求都是查询和修改缓存页一,直接操作缓存而不需要从磁盘加载,这就是缓存命中率高。

  2. 而缓存页二自加载到 Buffer Pool 后,只被查询和修改过一次,之后的100次请求中甚至没有一次是查询和修改它的,这就是缓存命中率低了。因为大部分请求都是操作其他缓存页,甚至要从磁盘中加载。

2、lru 链表的使用原理

InnoDB 存储引擎是利用 lru 链表完成上面的缓存命中率的。lru 就是 Least Recently Used,最近最少使用的意思。

ps:lru 链表也是类似于 free 链表和 flush 链表的数据结构。

当有磁盘数据页加载数据到缓存页时,会将缓存页对应的描述数据块放入 lru 链表的头部;后续只要查询或者修改了缓存页的数据,也会将对应描述数据块移到 lru 链表的头部去。

此时,lru 链表尾部的描述数据块对应的缓存页,必定是命中率最低的,也就是使用最少的缓存页,所以优先被淘汰的肯定是它。

3、lru 链表存在的问题

lru 链表的使用当然不会像上面的那么简单。

因为 MySQL 为了提高性能,提供了一个机制:预读机制

当你从磁盘上加载一个数据页的时候,他可能会连带着把这个数据页相邻的其他数据页,也加载到缓存里去。

这个机制会带来这么一个问题:连带的数据页可能在后面的查询或者修改中,并不会用到,但是它们却在 lru 链表的头部。

什么意思?

那就是,本来经常被用到的缓存页被压到 lru 链表的尾部去了,如果此时需要淘汰缓存页,命中率高的缓存页反而被淘汰掉了!

当然了,全表扫描也会带来同样的问题。

全表扫描会将表里所有的数据一次性加载到 Buffer Pool 来,但是却有很多数据在之后都不会用到。

4、冷热数据分离

什么是冷热分离?

简单点,就是将命中率高的数据和命中率低的数据分开,分成两块区域。

InnoDB 存储引擎就是利用冷热数据分离方案来解决上面的问题:将 lru 链表分为两部分,一部分是热数据区域链表,一部分是冷数据区域链表。

lru 链表的头节点指向热数据区域的链表头节点,lru 链表的尾节点指向冷数据区域的链表尾节点。

描述如图所示:

冷热分离的比例

由参数 innodb_old_blocks 控制,默认值为37,表示冷数据占所有数据的37%。

冷热分离的原理

磁盘中的数据页第一次加载到缓存页时,对应的描述数据块放到冷数据区域的链表头部,然后在 1s 后,如果再次访问这个缓存页,才会将缓存页对应的描述数据块移动到热数据区域的链表头部去。

这个 1s 由参数 innodb_old_blocks_time 指定,默认值是 1000 毫秒。

热数据区的优化

冷数据区的缓存页是在 1s 后再被访问到就移动到热数据区的链表头部。那么热数据区域的规则呢,是不是只要被访问就会移动到热数据区域的链表头部。

当然不是了。大家可以想一下,能留在热数据区域的缓存页,证明都是缓存命中率比较高的,会经常被访问到。如果每个缓存页被访问都移动到链表头部,那这个操作将会非常的频繁。

所以 InnoDB 存储引擎做了一个优化,只有在热数据区域的后 3/4 的缓存页被访问了,才会移动到链表头部;如果是热数据区域的前 1/4 的缓存页被访问到,它是不会被移动到链表头部去的。

lru 链表尾部的缓存页何时刷入磁盘?

当 free 链表为空了,此时需要将数据页加载到缓冲池里,就会 lru 链表的冷数据区域尾部的缓存页刷入磁盘,然后清空,再加载数据页的数据。

一条后台线程,运行一个定时任务,定时将 lru 链表的冷数据区域的尾部的一些缓存页刷入磁盘,然后清空,最后把他们对应的描述数据块加入到 free 链表中去。

当然了,除了 lru 链表尾部的缓存页会被刷入磁盘,还有的就是 flush 链表的缓存页。

后台线程同时也会在 MySQL 不繁忙的时候,将 flush 链表中的缓存页刷入磁盘中,这些缓存页的描述数据块会从 lru 链表和 flush 链表中移除,并加入到 free 链表中。

八、总结

到此,我已经将缓冲池 Buffer Pool介绍完毕了。

下面简单总结一下 Buffer Pool 从初始化到使用的整个流程。

1、MySQL 启动时会根据分配指定大小内存给 Buffer Pool,并且会创建一个个描述数据块和缓存页。

2、SQL 进来时,首先会根据数据的表空间和数据页编号查询 数据页缓存哈希表 中是否有对应的缓存页。

3、如果有对应的缓存页,则直接在 Buffer Pool中执行。

4、如果没有,则检查 free 链表看看有没有空闲的缓存页。

5、如果有空闲的缓存页,则从磁盘中加载对应的数据页,然后将描述数据块从 free 链表中移除,并且加入到 lru 链表的冷数据区域的链表头部。后面如果被修改了,还需要加入到 flush 链表中。

6、如果没有空闲的缓存页,则将 lru 链表的冷数据区域的链表尾部的缓存页刷回磁盘,然后清空,接着将数据页的数据加载到缓存页中,并且描述数据块会加入到 lru 链表的冷数据区域的链表头部。后面如果被修改了,还需要加入到 flush 链表中。

7、5或者6后,就接着在 Buffer Pool 中执行增删改查。

注意:5和6中,缓存页加入到冷数据区域的链表头部后,如果在 1s 后被访问,则将入到热数据区域的链表头部。

8、最后,就是描述数据块随着 SQL 语句的执行不断地在 free 链表、flush 链表和 lru 链表中移动了。

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 目录