Mysql中的Buffer pool

news2024/11/27 11:32:05

Buffer Pool在数据库里的地位

1、回顾一下Buffer Pool是个什么东西?

数据库中的Buffer Pool是个什么东西?其实他是一个非常关键的组件,数据库中的数据实际上最终都是要存放在磁盘文件上的,如下图所示。

但是我们在对数据库执行增删改操作的时候,不可能直接更新磁盘上的数据的,因为如果你对磁盘进行随机读写操作,那速度是相当的慢,随便一个大磁盘文件的随机读写操作,可能都要几百毫秒。如果要是那么搞的话,可能你的数据库每秒也就只能处理几百个请求了! 在对数据库执行增删改操作的时候,实际上主要都是针对内存里的Buffer Pool中的数据进行的,也就是实际上主要是对数据库的内存里的数据结构进行了增删改,如下图所示。

其实每个人都担心一个事,就是你在数据库的内存里执行了一堆增删改的操作,内存数据是更新了,但是这个时候如果数据库突然崩溃了,那么内存里更新好的数据不是都没了吗? MySQL就怕这个问题,所以引入了一个redo log机制,你在对内存里的数据进行增删改的时候,他同时会把增删改对应的日志写入redo log中,如下图。

万一你的数据库突然崩溃了,没关系,只要从redo log日志文件里读取出来你之前做过哪些增删改操作,瞬间就可以重新把这些增删改操作在你的内存里执行一遍,这就可以恢复出来你之前做过哪些增删改操作了。 当然对于数据更新的过程,他是有一套严密的步骤的,还涉及到undo log、binlog、提交事务、buffer pool脏数据刷回磁盘,等等。

2、Buffer Pool的一句话总结

Buffer Pool是数据库中我们第一个必须要搞清楚的核心组件,因为增删改操作首先就是针对这个内存中的Buffer Pool里的数据执行的,同时配合了后续的redo log、刷磁盘等机制和操作。

所以Buffer Pool就是数据库的一个内存组件,里面缓存了磁盘上的真实数据,然后我们的系统对数据库执行的增删改操作,其实主要就是对这个内存数据结构中的缓存数据执行的。

Buffer Pool这个内存数据结构到底长个什么样子?

1、如何配置你的Buffer Pool的大小?

我们应该如何配置你的Buffer Pool到底有多大呢? 因为Buffer Pool本质其实就是数据库的一个内存组件,你可以理解为他就是一片内存数据结构,所以这个内存数据结构肯定是有一定的大小的,不可能是无限大的。 这个Buffer Pool默认情况下是128MB,还是有一点偏小了,我们实际生产环境下完全可以对Buffer Pool进行调整。 比如我们的数据库如果是16核32G的机器,那么你就可以给Buffer Pool分配个2GB的内存,使用下面的配置就可以了。 [server] innodb_buffer_pool_size = 2147483648 如果你不知道数据库的配置文件在哪里以及如何修改其中的配置,那建议可以先在网上搜索一些MySQL入门的资料去看看,其实这都是最基础和简单的。 我们先来看一下下面的图,里面就画了数据库中的Buffer Pool内存组件

2、数据页:MySQL中抽象出来的数据单位

假设现在我们的数据库中一定有一片内存区域是Buffer Pool了,那么我们的数据是如何放在Buffer Pool中的?

我们都知道数据库的核心数据模型就是 表+字段+行 的概念,所以大家觉得我们的数据是一行一行的放在Buffer Pool里面的吗? 这就明显不是了,实际上MySQL对数据抽象出来了一个数据页的概念,他是把很多行数据放在了一个数据页里,也就是说我们的磁盘文件中就是会有很多的数据页,每一页数据里放了很多行数据,如下图所示。

所以实际上假设我们要更新一行数据,此时数据库会找到这行数据所在的数据页,然后从磁盘文件里把这行数据所在的数据页直接给加载到Buffer Pool里去。 也就是说,Buffer Pool中存放的是一个一个的数据页,如下图。

3、磁盘上的数据页和Buffer Pool中的缓存页是如何对应起来的?

实际上默认情况下,磁盘中存放的数据页的大小是16KB,也就是说,一页数据包含了16KB的内容。 而Buffer Pool中存放的一个一个的数据页,我们通常叫做缓存页,因为毕竟Buffer Pool是一个缓冲池,里面的数据都是从磁盘缓存到内存去的。 而Buffer Pool中默认情况下,一个缓存页的大小和磁盘上的一个数据页的大小是一一对应起来的,都是16KB。 我们看下图,我给图中的Buffer Pool标注出来了他的内存大小,假设他是128MB吧,然后数据页的大小是16KB。

4、缓存页对应的描述信息是什么?

对于每个缓存页,他实际上都会有一个描述信息,这个描述信息大体可以认为是用来描述这个缓存页的。 比如包含如下的一些东西:这个数据页所属的表空间、数据页的编号、这个缓存页在Buffer Pool中的地址以及别的一些杂七杂八的东西。 每个缓存页都会对应一个描述信息,这个描述信息本身也是一块数据,在Buffer Pool中,每个缓存页的描述数据放在最前面,然后各个缓存页放在后面。所以此时我们看下面的图,Buffer Pool实际看起来大概长这个样子 。

而且这里我们要注意一点,Buffer Pool中的描述数据大概相当于缓存页大小的5%左右,也就是每个描述数据大概是800个字节左右的大小,然后假设你设置的buffer pool大小是128MB,实际上Buffer Pool真正的最终大小会超出一些,可能有个130多MB的样子,因为他里面还要存放每个缓存页的描述数据。

思考

对于Buffer Pool而言,他里面会存放很多的缓存页以及对应的描述数据,那么假设Buffer Pool里的内存都用尽了,已经没有足够的剩余内存来存放缓存页和描述数据了,此时Buffer Pool里就一点内存都没有了吗?还是说Buffer Pool里会残留一些内存碎片呢? 如果你觉得Buffer Pool里会有内存碎片的话,那么你觉得应该怎么做才能尽可能减少Buffer Pool里的内存碎片呢?

在生产环境中,如何基于机器配置来合理设置Buffer Pool?

1、生产环境中应该给buffer pool设置多少内存?

今天这篇文章我们接着上一次讲解的Buffer Pool的一些内存划分的原理,来给大家最后总结一下,在生产环境中到底应该如何设置Buffer Pool的大小呢。 首先考虑第一个问题,我们现在数据库部署在一台机器上,这台机器可能有个8G、16G、32G、64G、128G的内存大小,那么此时buffer pool应该设置多大呢? 有的人可能会想,假设我有32G内存,那么给buffer pool设置个30GB得了,这样的话,MySQL大量的crud操作都是基于内存来执行的,性能那是绝对高! 这么想就大错特错了,虽然你的机器有32GB的内存,但是你的操作系统内核就要用掉起码几个GB的内存!你的机器上可能还有别的东西在运行!你的数据库里除了buffer pool是不是还有别的内存数据结构! 所以上面那种想法是绝对不可取的! 如果你胡乱设置一个特别大的内存给buffer,会导致你的mysql启动失败的,他启动的时候就发现操作系统的内存根本不够用! 所以通常来说,我们建议一个比较合理的、健康的比例,是给buffer pool设置你的机器内存的50%~60%左右 比如你有32GB的机器,那么给buffer设置个20GB的内存,剩下的留给OS和其他人来用,这样比较合理一些。 假设你的机器是128GB的内存,那么buffer pool可以设置个80GB左右,大概就是这样的一个规则。

2、buffer pool总大小=(chunk大小 * buffer pool数量)的2倍数

接着确定了buffer pool的总大小之后,就得考虑一下设置多少个buffer pool,以及chunk的大小。 此时有一个很关键的公式:buffer pool总大小 = (chunk大小 * buffer pool数量) 的倍数 比如默认的chunk大小是128MB,那么此时如果你的机器的内存是32GB,你打算给buffer pool总大小在20GB左右,此时你的buffer pool的数量应该是多少个呢?

假设你的buffer pool的数量是16个,这是没问题的,那么此时chunk大小 * buffer pool的数量 = 16 * 128MB = 2048MB,然后buffer pool总大小如果是20GB,此时buffer pool总大小就是2048MB的10倍,这就符合规则了。 当然,此时你可以设置多一些buffer pool数量,比如设置32个buffer pool,那么此时buffer pool总大小(20GB)就是(chunk大小128MB * 32个buffer pool)的5倍,也是可以的。 那么此时你的buffer pool大小就是20GB,然后buffer pool数量是32个,每个buffer pool的大小是640MB,然后每个buffer pool包含5个128MB的chunk,算下来就是这么一个结果了。

3、一点总结

数据库在生产环境运行时,必须根据机器的内存设置合理的buffer pool的大小,然后设置buffer pool的数量,这样可以尽可能的保证你的数据库的高性能和高并发能力。 在线上运行时,buffer pool是有多个的,每个buffer pool里多个chunk但是共用一套链表数据结构,然后执 行crud的时候,就会不停的加载磁盘上的数据页到缓存页里来,然后会查询和更新缓存页里的数据,同时维护一系列的链表结构。 然后后台线程定时根据lru链表和flush链表,去把一批缓存页刷入磁盘释放掉这些缓存页,同时更新free链表。 如果执行crud的时候发现缓存页都满了,没法加载自己需要的数据页进缓存,此时就会把lru链表冷数据区域的缓存页刷入磁盘,然后加载自己需要的数据页进来。 整个buffer pool的结构设计以及工作原理,就是上面我们总结的这套东西了,大家只要理解了这个,首先你对MySQL执行crud的时候,是如何在内存里查询和更新数据的,你就彻底明白了。

接着我们后面继续探索undo log、redo log、事务机制、事务隔离、锁机制,这些东西,一点点就把MySQL他的数据更新、事务、锁这些原理,全部搞清楚了,同时中间再配合穿插一些生产经验、实战案例。

4、SHOW ENGINE INNODB STATUS

当你的数据库启动之后,你随时可以通过上述命令,去查看当前innodb里的一些具体情况,执行SHOW ENGINE INNODB STATUS就可以了。此时你可能会看到如下一系列的东西:

Total memory allocated xxxx;
Dictionary memory allocated xxx
Buffer pool size xxxx
Free buffers xxx
Database pages xxx
Old database pages xxxx
Modified db pages xx
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young xxxx, not young xxx
xx youngs/s, xx non-youngs/s
Pages read xxxx, created xxx, written xxx
xx reads/s, xx creates/s, 1xx writes/s
Buffer pool hit rate xxx / 1000, young-making rate xxx / 1000 not xx / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: xxxx, unzip_LRU len: xxx
I/O sum[xxx]:cur[xx], unzip sum[16xx:cur[0]
​

下面解释一下这里的东西,主要讲解这里跟buffer pool相关的一些东西。

  1. Total memory allocated,这就是说buffer pool最终的总大小是多少

  2. Buffer pool size,这就是说buffer pool一共能容纳多少个缓存页

  3. Free buffers,这就是说free链表中一共有多少个空闲的缓存页是可用的

  4. Database pages和Old database pages,就是说lru链表中一共有多少个缓存页,以及冷数据区域里的缓存页数量

  5. Modified db pages,这就是flush链表中的缓存页数量

  6. Pending reads和Pending writes,等待从磁盘上加载进缓存页的数量,还有就是即将从lru链表中刷入磁盘的数量、即将从flush链表中刷入磁盘的数量

  7. Pages made young和not young,这就是说已经lru冷数据区域里访问之后转移到热数据区域的缓存页的数 量,以及在lru冷数据区域里1s内被访问了没进入热数据区域的缓存页的数量

  8. youngs/s和not youngs/s,这就是说每秒从冷数据区域进入热数据区域的缓存页的数量,以及每秒在冷数据区域里被访问了但是不能进入热数据区域的缓存页的数量

  9. Pages read xxxx, created xxx, written xxx,xx reads/s, xx creates/s, 1xx writes/s,这里就是说已经读取、创建和写入了多少个缓存页,以及每秒钟读取、创建和写入的缓存页数量

  10. Buffer pool hit rate xxx / 1000,这就是说每1000次访问,有多少次是直接命中了buffer pool里的缓存的

  11. young-making rate xxx / 1000 not xx / 1000,每1000次访问,有多少次访问让缓存页从冷数据区域移动到了热数据区域,以及没移动的缓存页数量

  12. LRU len:这就是lru链表里的缓存页的数量

  13. I/O sum:最近50s读取磁盘页的总数

  14. I/O cur:现在正在读取磁盘页的数量

bufferpoll实例个数及chunk个数:

innodb_buffer_pool_instances

在多线程环境下,访问
Buffer Pool 中的各种链表都需要加锁处理啥的,在 Buffer Pool 特别大而且多线程并发访问特别高的情况下, 单一的 Buffer Pool 可能会影响请求的处理速度。所以在 Buffer Pool 特别大的时候,我们可以把它们拆分成若 干个小的 Buffer Pool ,每个 Buffer Pool 都称为一个 实例 ,它们都是独立的,独立的去申请内存空间,独立 的管理各种链表,独立的吧啦吧啦,所以在多线程并发访问时并不会相互影响,从而提高并发处理能力。我们可 以在服务器启动的时候通过设置 innodb_buffer_pool_instances 的值来修改 Buffer Pool 实例的个数,比方说
这样:
[server]
innodb_buffer_pool_instances = 2

 

那每个 Buffer Pool 实例实际占多少内存空间呢?其实使用这个公式算出来的:
innodb_buffer_pool_size/innodb_buffer_pool_instances
也就是总共的大小除以实例的个数,结果就是每个 Buffer Pool 实例占用的大小。
不过也不是说 Buffer Pool 实例创建的越多越好,分别管理各个 Buffer Pool 也是需要性能开销的,设计 InnoDB 的大叔们规定: innodb_buffer_pool_size 的值小于 1G 的时候设置多个实例是无效的, InnoDB 会默认把 innodb_buffer_pool_instances 的值修改为 1 。而我们鼓励在 Buffer Pool 大小或等于 1G 的时候设置多个 Buffer Pool 实例。

 

innodb_buffer_pool_chunk_size

MySQL 5.7.5 之前, Buffer Pool 的大小只能在服务器启动时通过配置 innodb_buffer_pool_size 启动参数 来调整大小,在服务器运行过程中是不允许调整该值的。不过设计 MySQL 的大叔在 5.7.5 以及之后的版本中支持 了在服务器运行过程中调整 Buffer Pool 大小的功能,但是有一个问题,就是每次当我们要重新调整 Buffer Pool 大小时,都需要重新向操作系统申请一块连续的内存空间,然后将旧的 Buffer Pool 中的内容复制到这一 块新空间,这是极其耗时的。所以设计 MySQL 的大叔们决定不再一次性为某个 Buffer Pool 实例向操作系统申请 一大片连续的内存空间,而是以一个所谓的 chunk 为单位向操作系统申请空间。也就是说一个 Buffer Pool 实例
其实是由若干个 chunk 组成的,一个 chunk 就代表一片连续的内存空间,里边儿包含了若干缓存页与其对应的控 制块,画个图表示就是这样:
正是因为发明了这个 chunk 的概念,我们在服务器运行期间调整 Buffer Pool 的大小时就是以 chunk 为单位增 加或者删除内存空间,而不需要重新向操作系统申请一片大的内存,然后进行缓存页的复制。这个所谓的 chunk 的大小是我们在启动操作 MySQL 服务器时通过 innodb_buffer_pool_chunk_size 启动参数指定的,它的默认值 是 134217728 ,也就是 128M 。不过需要注意的是, innodb_buffer_pool_chunk_size 的值只能在服务器启动时指
定,在服务器运行过程中是不可以修改的
innodb_buffer_pool_size 必须是 innodb_buffer_pool_chunk_size × innodb_buffer_pool_instances 的 倍数(这主要是想保证每一个 Buffer Pool 实例中包含的 chunk 数量相同)。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/627084.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023最新Java面试八股文,阿里/腾讯 / 美团 / 字节 1 000道 Java 中高级面试题

企业调薪、裁员、组织架构调整等等,坏消息只多不少,最近也有很多来咨询跳槽的朋友,都是因为之前的公司出现了比较大的薪资和组织变动 近期有许多粉丝非常关注最新的面试题!于是小编去各大平台搜罗了一份近期大厂面试的一些内容&a…

基础工程(cubeide串口调试,printf实现,延时函数)

0.基础工程(cubeide串口调试,printf实现,延时函数) 文章目录 0.基础工程(cubeide串口调试,printf实现,延时函数)外部时钟源CLOCK(RCC)系统时钟SYS与DEBUG设置UART串口设置cubeide设置…

世界研发管理组织在美国成立,中国籍研发管理专家江新安当选总干事

World R&D Management Organization世界研发管理组织(WRDMO)由来自世界各地的研发管理研究组织,创新技术研究机构,院校以及研发管理咨询机构联合发起。是一个具有开放性,无党派性,非营利性的国际先进研…

如从亿点点失误,到一点点失误,我是如何做的【工作失误怎么办】

前言 只要我们还在做事,或者说还活着,就没有不犯错的时候。作为一名前端搬砖工,哪怕工作中再仔细小心,也免不了一些失误。 那这是不是说,失误很正常,改了就是嘛? 这么说好像没错。作为失误本…

【计算机组成与体系结构Ⅰ】知识点整理

第一章 计算机系统概论 1.1 从源文件到可执行文件 .c源程序、.i源程序、.s汇编语言程序、.o可重定位目标程序、可执行目标程序;后两个为二进制,前面为文本 1.2 可执行文件的启动和执行 冯诺依曼结构计算机模型的5大基本部件:运算器、控制…

【ChatGLM】使用ChatGLM-6B-INT4模型进行P-Tunning训练记录及参数讲解

文章目录 模型训练步骤参数含义名词解释欠拟合泛化能力收敛性梯度爆炸 初步结论 小结 模型训练 首先说明一下训练的目的:提供本地问答知识文件,训练之后可以按接近原文语义进行回答,类似一个问答机器人。 步骤 安装微调需要的依赖&#xf…

C++【哈希表封装unordered_map/set】—含有源代码

文章目录 (1)修改原哈希表(2)迭代器(3)最后一步(4)关于key是自定义类型的额外补充(面试题)(5)源代码 (1)修改原哈希表 和红黑树封装一…

【链表Part01】| 203.移除链表元素、707.设计链表、206.反转链表

目录 ✿LeetCode203.移除链表元素❀ ✿LeetCode707.设计链表❀ ✿LeetCode206.反转链表❀ ✿LeetCode203.移除链表元素❀ 链接:203.移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点&#xff…

python数据分析

一、数据处理 1.爬取数据 我们将使用Python的requests和BeautifulSoup库来爬取数据。在这个示例中,我们将爬取豆瓣电影Top250的数据。 import requests from bs4 import BeautifulSoup url https://movie.douban.com/top250 headers {User-Agent: Mozilla/5.0 …

策略设计模式解读

目录 问题引进 鸭子问题 传统方案解决鸭子问题的分析和代码实现 传统的方式实现的问题分析和解决方案 策略模式基本介绍 基本介绍 策略模式的原理类图 策略模式解决鸭子问题 策略模式的注意事项和细节 问题引进 鸭子问题 编写鸭子项目,具体要求如下: 1) 有…

【GlobalMapper精品教程】059:基于las点云创建数字高程地形并二三维着色显示

本文讲述在globalmapper免费中文版中基于地形点云las数据创建数字高程地形、数字高程二三维联动可视化并进行数字高程着色显示。 文章目录 一、加载地形点云las数据二、创建数字高程地形三、数字高程二三维联动可视化四、数字高程着色显示相关阅读:ArcGIS实验教程——实验二十…

如何看待 Facebook 上线支付功能?

随着科技的不断进步,电子支付在我们的生活中变得越来越普遍。最近,Facebook宣布推出自己的支付功能,这引起了广泛的关注和讨论。作为世界上最大的社交媒体平台之一,Facebook进入支付领域的举措无疑具有重要意义。那么,…

Jetpack Compose:使用PagerIndicator和Infinity实现滚动的HorizontalPager

Jetpack Compose:使用PagerIndicator和Infinity实现滚动的HorizontalPager 可能你已经知道,Jetpack Compose 默认不包含内置的ViewPager组件。然而,我们可以通过在 build.gradle 文件中添加 accompanist 库依赖,将 ViewPager 功能…

有了这套方案,企业降本增效不再是纸上谈兵 (2)

一、生存压力逼近,企业如何应对经济下行残酷挑战? 当前市场经济下滑,客户预算紧缩和投资削减可能导致IT项目推迟或取消,从而直接影响公司收入和盈利能力。各大厂商都在陆续裁员或调整业务,以人力等成本为主的IT公司也必…

双塔模型dssm实践

最近在学习向量召回,向量召回不得不用到dssm双塔模型,双塔模型的原理非常简单,就是用两个任务塔,一个是query侧的query任务塔,另一个是doc侧的doc任务塔,任务塔向上抽象形成verctor隐向量后,用c…

【多同步挤压变换】基于多同步挤压变换处理时变信号和噪声信号研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

2022年国赛高教杯数学建模B题无人机遂行编队飞行中的纯方位无源定位解题全过程文档及程序

2022年国赛高教杯数学建模 B题 无人机遂行编队飞行中的纯方位无源定位 原题再现 无人机集群在遂行编队飞行时,为避免外界干扰,应尽可能保持电磁静默,少向外发射电磁波信号。为保持编队队形,拟采用纯方位无源定位的方法调整无人机…

win10录屏软件哪个好用?强烈推荐这3款!

案例:想要录制我的电脑屏幕,但是不知道如何选择合适的录屏工具,有没有好用的win10录屏软件? 【我想找一款好用的win10录屏工具,录制我的电脑屏幕,但是找了很久还没有找到,大家有好用的录屏软件…

Kibana:使用 Kibana 自带数据进行可视化(二)

在今天的练习中,我们将使用 Kibana 自带的数据来进行一些可视化的展示。希望对刚开始使用 Kibana 的用户有所帮助。这个是继上一篇文章 “Kibana:使用 Kibana 自带数据进行可视化(一)” 的续篇。 前提条件 如果你还没有安装好自己…

占据80%中国企业出海市场,亚马逊云科技如何为出海客户提供更多资源和附加值

亚马逊云科技就可以做到,作为占据80%中国企业出海市场的亚马逊云科技,其覆盖全球的业务体系,从亚马逊海外购、亚马逊全球开店、亚马逊智能硬件与服务,Amazon Alexa,Amazon Music都是属于亚马逊云科技“梦之队”的一员。…