缓冲池的用处

对于使用 InnoDB 作为存储引擎的表来说,不管是用于存储用户数据的索引,还是各种系统数据,都是以页的形式存放在表空间中的,而所谓的表空间只是 InnoDB 对文件系统上一个或几个实际文件的抽象,也就实际数据说到底还是存储在磁盘上的。

磁盘的速度很慢,怎么能配得上“快如闪电”的CPU 呢?

InnoDB 存储引擎在处理客户端的请求时,当需要访问某个页的数据时,就会把完整的页的数据全部加载到内存中。

也就是说即使我们只需要访问一个页的一条记录,那也需要先把整个页的数据加载到内存中。

缓冲池内部组成

缓冲池中默认的缓存页大小和在磁盘上默认的页大小是一样的,一般是16KB。

为了更好的管理这些在缓冲池中的缓存页,InnoDB为每一个缓存页都创建了一些所谓的控制信息。

这些控制信息包括该页所属的表空间编号、页号、缓存页在缓冲池中的地址、链表节点信息、一些锁信息。

缓冲池的一些参数: SHOW VARIABLES LIKE 'innodb_buffer_pool%'; free 链表 当最初启动MySQL服务器的时候,此时并没有真实的磁盘页被缓存到缓冲池中,之后随着程序的运行,会不断的有磁盘上的页被缓存到缓冲池中。

从磁盘上读取一个页到缓冲池中的时候该放到哪个缓存页的位置呢?

思路:区分缓冲池中哪些缓存页是空闲的,哪些已经被使用了。

把所有空闲的缓存页对应的控制块作为节点放到一个链表中,这个链表叫作 free 链表。

flush 链表

如果我们修改了缓冲池中某个缓存页的数据,那它就和磁盘上的页不一致了,这样的缓存页也被称为脏页(dirty page)。

最简单的做法就是每发生一次修改就立即同步到磁盘上对应的页上,但是频繁的往磁盘中写数据会严重的影响程序的性能。

所以,Innodb 创建了一个存储脏页的链表,凡是修改过的缓存页对应的控制块都会作为一个节点加入到一个链表中,在未来的某个时间点进行同步。这个链表叫做 flush 链表。

缓存不够的窘境

缓冲池对应的内存大小毕竟是有限的,如果需要缓存的页占用的内存大小超过了缓冲池大小,也就是已经没有多余的空闲缓存页的时候怎么办?

把某些旧的缓存页从缓冲池中移除,然后再把新的页放进来。

移除哪些缓存页?这就需要引入缓存淘汰机制了。

缓存淘汰机制

缓存淘汰有以下两个目的:

  • 实现淘汰
  • 使缓存命中率高

缓存淘汰机制比较常用的是用 LRU (Least recently used)算法。

传统LRU

LRU 的两种情况:

(1)页已经在缓冲池里,那就只做“移至”LRU头部的动作,而没有页被淘汰;

(2)页不在缓冲池里,除了做“放入”LRU头部的动作,还要做“淘汰”LRU尾部页的动作;

在 InnoDB 中,传统的 LRU 会遇到两个问题:

(1)预读失效;

(2)缓冲池污染;

什么是预读失效?

由于预读 (Read-Ahead),提前把页放入了缓冲池,但最终 MySQL 并没有从页中读取数据,称为预读失效。

如何对预读失效进行优化?

要优化预读失效,思路是:

(1)让预读失败的页,停留在缓冲池 LRU 里的时间尽可能短;

(2)让真正被读取的页,才挪到缓冲池 LRU 的头部;以保证,真正被读取的热数据留在缓冲池里的时间尽可能长。

具体方法是:

(1)将LRU分为两个部分

  • new 区(new sublist)
  • old 区(old sublist)

(2)两个区首尾相连,即:new 区的尾(tail)连接着 old 区的头(head);

(3)新页(例如被预读的页)加入缓冲池时,只加入到 old 区头部: 如果数据真正被读取(预读成功),才会加入到 new 区的头部 如果数据没有被读取,则会比 new 区里的“热数据页”更早被淘汰出缓冲池

改进版缓冲池LRU能够很好的解决“预读失败”的问题。

查看系统变量 innodb_old_blocks_pct 的值来确定old区域在LRU链表中所占的比例 SHOW VARIABLES LIKE 'innodb_old_blocks_pct';

什么是 MySQL 缓冲池污染? 当某一个SQL语句,要批量扫描大量数据时,可能导致把缓冲池的所有页都替换出去,导致大量热数据被换出,MySQL性能急剧下降,这种情况叫缓冲池污染。

例如,有一个数据量较大的用户表,当执行 select * from user where name like "%test%";

要优化缓冲池污染,思路是:

(1)不让批量扫描的大量数据进入到 new 区;

(2)让真正被读取的页,才挪到缓冲池 LRU 的头部;

具体实现: 加入了一个“old 区停留时间”的机制: 在 old 区域的缓存页进行第一次访问时就在它对应的控制块中记录下来这个访问时间,如果后续再次访问的时间与第一次访问的时间在某个时间间隔内(即该缓存页在 old 区的存在时间在某个时间间隔内),那么该页面就不会被从old 区移动到 new 区的头部。

上述的全表扫描执行:

(1)扫描过程中,需要新插入的数据页,都被放到old区

(2)一个数据页会有多条记录,因此一个数据页会被访问多次

(3)由于是顺序扫描,数据页的第一次被访问和最后一次被访问的时间间隔不会超过1S,因此还是会留在old区

(4) 继续扫描,之前的数据页再也不会被访问到,因此也不会被移到 new 区,最终很快被淘汰这个间隔时间是由系统变量 innodb_old_blocks_time 控制的。SHOW VARIABLES LIKE 'innodb_old_blocks_time';配置缓冲池时的注意事项 innodb_buffer_pool_size
innodb_buffer_pool_chunk_size ×
innodb_buffer_pool_instances 的倍数(这主要是想保证每一个 缓冲池 实例中包含的 chunk 数量相同)。

查看Buffer Pool的状态信息

SHOW ENGINE INNODB STATUSG

一些参数如下:

  • Total memory allocated :代表 Buffer Pool 向操作系统申请的连续内存空间大小,包括全部控制块、缓存页、以及碎片的大小。
  • Buffer pool size:代表该 Buffer Pool 可以容纳多少缓存页,单位是页
  • Free buffers:代表当前 Buffer Pool 还有多少空闲缓存页,也就是 free 链表中还有多少个节点。
  • Database pages:代表 LRU 链表中的页的数量,包含 new 和 old 两个区域的节点数量。
  • Old database pages:代表 LRU 链表 old 区域的节点数量。
  • Modified db pages:代表脏页数量,也就是 flush 链表中节点的数量。

总结

1、磁盘太慢,用内存作为缓存很有必要。
2、缓冲池本质上是InnoDB向操作系统申请的一段连续的内存空间,可以通过innodb_buffer_pool_size 来调整它的大小。
3、InnoDB 使用了许多链表来管理缓冲池。
4、缓冲池的常见管理算法是 LRU
5、InnoDB 对普通 LRU 进行了优化:分为 new 区和 old 区,加入“停留时间”机制。

作者:JeffreyC链接:https://juejin.im/post/5eccf7c3f265da76f525d333

分页缓冲池占用很高怎么解决_聊点深的:解析MySQL,看看InnoDB 缓冲池(buffer pool) 工作原理...相关推荐

  1. 分页缓冲池占用很高怎么解决_一次线上服务高 CPU 占用优化实践

    线上有一个非常繁忙的服务的 JVM 进程 CPU 经常跑到 100% 以上,下面写了一下排查的过程.通过阅读这篇文章你会了解到下面这些知识. Java 程序 CPU 占用高的排查思路 可能造成线上服务 ...

  2. mysql分页缓冲池占用很高怎么解决_缓冲池(buffer pool),这次彻底懂了!!!

    https://blog.csdn.net/weixin_40009393/article/details/111103350 应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cac ...

  3. 缓冲多少数据_聊点深的:解析MySQL,看看InnoDB 缓冲池(buffer pool) 工作原理

    缓冲池的用处 对于使用 InnoDB 作为存储引擎的表来说,不管是用于存储用户数据的索引,还是各种系统数据,都是以页的形式存放在表空间中的,而所谓的表空间只是 InnoDB 对文件系统上一个或几个实际 ...

  4. WmiPrvSE.exe是什么进程?WMI Provider Host占用很高CPU怎么办?

    WmiPrvSE.exe是什么进程?WMI Provider Host占用很高CPU怎么办? 时间:2018-01-06 来源:系统之家 作者:chunhua WmiPrvSE.exe是什么进程?WM ...

  5. Win7 svchost.exe LOCAL_SERVICE占用CPU高的解决办法

    使用环境(蓝色粗体字为特别注意内容) 1.软件环境:Windows7 32 bit 旗舰版 2.参考文献:①http://blog.sina.com.cn/s/blog_7bf0c30f0100sk2 ...

  6. XSSFWorkbook导致CPU占用很高

    XSSFWorkbook导致CPU占用很高 将微信支付的账单同步至云存储 业务需求 科普 解决方案 将微信支付的账单同步至云存储 业务需求 https://pay.weixin.qq.com/wiki ...

  7. 荣耀linux版开机内存占用高,win10开机内存占用50怎么办_win10一开机内存就占用过高的解决方法...

    win10开机内存占用50怎么办?相信很多用户都遇到过这种情况,但内存占用过高会导致我们使用电脑变得很不流畅,那要怎么解决这一问题呢?下面小编就以win10旗舰版为例,来为大家整理了win10一开机内 ...

  8. win10系统system进程占用cpu高怎么解决

    Win10系统经常发现任务管理器中的system进程占用了很高的cpu内存,一直在50%左右,这也导致了多项应用程序运行卡顿,本人是家庭激活版本,也在网上搜索win10系统system进程占用cpu高 ...

  9. windows7系统内存占用过高的解决方法

    电脑的内存空间取决了电脑的运行流畅度,时间一久内存就会爆满导致占用过高这样就会使电脑变得延迟,那么windows7系统内存占用过高怎么办呢?下面就一起来看看windows7系统内存占用过高的解决方法吧 ...

最新文章

  1. python爬虫原理-干货|如何入门 Python 爬虫?爬虫原理及过程详解
  2. [转]虚函数实现原理
  3. 关于FTP的两种连接模式
  4. AFDX(ARINC664)的交换机规范
  5. 浪潮FS6700 思科MDS 9148S光纤通道交换机图形化配置方法,小白也能轻松上手
  6. 论文阅读:在Stiefel流形上的黎曼优化
  7. 小程序实现城市搜索功能
  8. html怎么用css文件怎么打开,css文件用什么打开?
  9. RK3399驱动开发 | 08 - RK3399显示系统详解(基于RK SDK Linux 4.4.194内核)
  10. Java中notify() 和 notifyAll()的区别
  11. 上海市计算机学会-买二送一
  12. Java高级框架——Spring学习
  13. 计算机网络工程师题库华为,近五年华为各类工程师面试精典题库及答案详解.pdf...
  14. 测试人员如何面对开发人员的洗脑?
  15. 【知乎】来自知乎上的用户家庭智能娱乐机器人
  16. 一步一步教你使用虚拟机及安装windows
  17. edge 此项内容已下载并添加到 Chrome 中。_微软推出的逆天神器,让我抛弃用了5年的 Chrome...
  18. python使用谷歌翻译google_translator失效或者报错
  19. 如何解决 img 标签的 src 属性存在跨域问题
  20. Dell Display Manager检测不到dell显示器

热门文章

  1. 数据分析能力到底有多重要
  2. Request爬取网站(seo.chinaz.com)百度权重的查询结果
  3. 基于以太坊的去中心化宠物商店构建教程
  4. LeakCanary: 让内存泄露无所遁形
  5. java并发编程与线程安全
  6. OSChina 周五乱弹 —— 静静的思考下人生
  7. Linux中的Kdump
  8. Puppet dashboard安装
  9. 关于java 绝对值得收藏的书籍
  10. 【转】排除被冲销的物料凭证