MySQL—缓存

这篇具有很好参考价值的文章主要介绍了MySQL—缓存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

为什么要有Buffer Pool

虽然说MySQL的数据是存储在磁盘中,但是也不能每次都从磁盘里面读取数据,这样性能是极差的。所以InnoDB存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写能力。

MySQL—缓存,MySQL,mysql,缓存,数据库

有了缓冲池后:

  • 当读取数据时,如果数据存在于 Buffer Pool 中,客户端就会直接读取 Buffer Pool 中的数据,否则再去磁盘中读取。
  • 当修改数据时,首先是修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页,最后由后台线程将脏页写入到磁盘。

buffer pool有多大

Buffer Pool 是在 MySQL 启动的时候,向操作系统申请的一片连续的内存空间,默认配置下 Buffer Pool 只有 128MB 。可以通过调整 innodb_buffer_pool_size 参数来设置 Buffer Pool 的大小,一般建议设置成可用物理内存的 60%~80%。

buffer pool缓存什么

InnoDB会把存储的数据划分为若干个页,以页作为磁盘和内存交互的基本单位,一个页默认大小为16KB,MySQL启动时,InnoDB会为buffer pool申请一篇连续的内存空间,然后按照默认的16KB的大小划分出一个个的页,buffer pool中的页就叫做缓存页。

Buffer Pool 除了缓存「索引页」和「数据页」,还包括了 undo 页,插入缓存、自适应哈希索引、锁信息等等。

MySQL—缓存,MySQL,mysql,缓存,数据库

为了更好的管理这些在 Buffer Pool 中的缓存页,InnoDB 为每一个缓存页都创建了一个控制块,控制块信息包括「缓存页的表空间、页号、缓存页地址、链表节点」等等。

控制块也是占有内存空间的,它是放在 Buffer Pool 的最前面,接着才是缓存页,如下图:

MySQL—缓存,MySQL,mysql,缓存,数据库

上图中控制块和缓存页之间灰色部分称为碎片空间。

如何管理Buffer Pool

如何管理空闲页

为了能够快速找到空闲的缓存页,可以使用链表结构,将空闲缓存页的「控制块」作为链表的节点,这个链表称为 Free 链表(空闲链表)。

MySQL—缓存,MySQL,mysql,缓存,数据库

Free 链表上除了有控制块,还有一个头节点,该头节点包含链表的头节点地址,尾节点地址,以及当前链表中节点的数量等信息。

Free 链表节点是一个一个的控制块,而每个控制块包含着对应缓存页的地址,所以相当于 Free 链表节点都对应一个空闲的缓存页。

有了 Free 链表后,每当需要从磁盘中加载一个页到 Buffer Pool 中时,就从 Free链表中取一个空闲的缓存页,并且把该缓存页对应的控制块的信息填上,然后把该缓存页对应的控制块从 Free 链表中移除。

如何管理脏页

buffer pool不仅提高读性能,还要提高写性能。在更新数据的时候,不需要每次都要写入磁盘,而是将buffer pool对应的缓存页标记为脏页,然后由后台线程将脏页写入到磁盘。

那为了能快速知道哪些缓存页是脏的,于是就设计出 Flush 链表,它跟 Free 链表类似的,链表的节点也是控制块,区别在于 Flush 链表的元素都是脏页。

MySQL—缓存,MySQL,mysql,缓存,数据库

如何提高缓存命中率

使用LRU算法,该算法的思路是,链表头部的节点是最近使用的,而链表末尾的节点是最久没被使用的。那么,当空间不够了,就淘汰最久没被使用的节点,从而腾出空间。

简单的 LRU 算法并没有被 MySQL 使用,因为简单的 LRU 算法无法避免下面这两个问题:

  • 预读失效;
  • Buffer Pool 污染;

预读失效

先来说说 MySQL 的预读机制。程序是有空间局部性的,靠近当前被访问数据的数据,在未来很大概率会被访问到。所以,MySQL 在加载数据页时,会提前把它相邻的数据页一并加载进来,目的是为了减少磁盘 IO。但是可能这些被提前加载进来的数据页,并没有被访问,相当于这个预读是白做了,这个就是预读失效

怎么解决预读失效而导致缓存命中率降低的问题?

最好就是让预读的页停留在 Buffer Pool 里的时间要尽可能的短,让真正被访问的页才移动到 LRU 链表的头部,从而保证真正被读取的热数据留在 Buffer Pool 里的时间尽可能长。MySQL 是这样做的,它改进了 LRU 算法,将 LRU 划分了 2 个区域:old 区域 和 young 区域。young 区域在 LRU 链表的前半部分,old 区域则是在后半部分,如下图:

MySQL—缓存,MySQL,mysql,缓存,数据库

划分这两个区域后,预读的页就只需要加入到 old 区域的头部,当页被真正访问的时候,才将页插入 young 区域的头部。如果预读的页一直没有被访问,就会从 old 区域移除,这样就不会影响 young 区域中的热点数据。

buffer pool污染

当某一个 SQL 语句扫描了大量的数据时,在 Buffer Pool 空间比较有限的情况下,可能会将 Buffer Pool 里的所有页都替换出去,导致大量热数据被淘汰了,等这些热数据又被再次访问的时候,由于缓存未命中,就会产生大量的磁盘 IO,MySQL 性能就会急剧下降,这个过程被称为 Buffer Pool 污染

怎么解决出现 Buffer Pool 污染而导致缓存命中率下降的问题?

MySQL 是这样做的,进入到 young 区域条件增加了一个停留在 old 区域的时间判断。具体是这样做的,在对某个处在 old 区域的缓存页进行第一次访问时,就在它对应的控制块中记录下来这个访问时间:

  • 如果后续的访问时间与第一次访问的时间在某个时间间隔内,那么该缓存页就不会被从 old 区域移动到 young 区域的头部
  • 如果后续的访问时间与第一次访问的时间不在某个时间间隔内,那么该缓存页移动到 young 区域的头部

这个间隔时间是由 innodb_old_blocks_time 控制的,默认是 1000 ms。也就说,只有同时满足「被访问」与「在 old 区域停留时间超过 1 秒」两个条件,才会被插入到 young 区域头部,这样就解决了 Buffer Pool 污染的问题 。另外,MySQL 针对 young 区域其实做了一个优化,为了防止 young 区域节点频繁移动到头部。young 区域前面 1/4 被访问不会移动到链表头部,只有后面的 3/4被访问了才会。文章来源地址https://www.toymoban.com/news/detail-647533.html

脏页什么时候会被刷入到磁盘

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

到了这里,关于MySQL—缓存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot+redis+mysql+quartz-通过Java操作jedis定时使用lua脚本获取缓存数据并更新数据库

    springboot+redis+mysql+quartz-通过Java操作jedis定时使用lua脚本获取缓存数据并更新数据库 代码讲解:7.1点赞功能-定时持久化到数据库-Java整合lua_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1ZX4y1H7JT/ 代码: blogLike_schedule/like07 · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com) https://gitee

    2024年02月13日
    浏览(57)
  • 【MySQL 】MySQL 创建数据库, MySQL 删除数据库,MySQL 选择数据库

    作者简介: 辭七七,目前大一,正在学习C/C++,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: 七七的闲谈 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖 我们可以在登陆 MySQL 服务后,使用 create 命令创建数据库,语法如下: 以下命令简单的演示了创建数据库的过程,

    2024年02月13日
    浏览(101)
  • 【MySQL数据库】初识MySQL数据库、安装MySQL

    在今天的数字化世界中,数据是企业和个人的重要资产。管理和存储数据变得至关重要,而 MySQL 数据库是一种备受欢迎的开源关系型数据库管理系统,它提供了稳定、可靠、高性能的数据存储解决方案。本文将介绍 MySQL 数据库的基本概念和安装过程,以便初学者能够轻松上

    2024年02月08日
    浏览(65)
  • 初识MySQL数据库——“MySQL数据库”

    各位CSDN的uu们你们好呀,小雅兰好久没有更文啦,确实是心有余而力不足,最近学习的内容太难了,这篇博客又是小雅兰的新专栏啦,主要介绍的是一些MySQL数据库的知识点,下面,让我们进入初识MySQL数据库的世界吧 为什么要使用数据库 数据库与数据库管理系统 MySQL介绍

    2024年02月06日
    浏览(54)
  • 【MySQL数据库】MySQL数据库管理

    Structure Query Language(结构化查询语言)简称SQL,它被美国国家标准局(ANSI)确定为关系型数据库语言的美国标准,后被国际化标准组织(ISO)采纳为关系数据库语言的国际标准。数据库管理系统可以通过SQL管理数据库;定义和操作数据,维护数据的完整性和安全性。 数据:(data)

    2024年02月08日
    浏览(52)
  • MySQL数据库:数据库管理系统与安装MySQL数据库

    目录 一、理论 1.数据库管理系统 2.关系型数据库 3.数据库 4.MySQL数据库 5.MySQL部署 二、实验 1.yum安装MySQL 2.编译安装MySQL 3.配置MySQL数据库的Tab补全  三、问题 1.数据库登录报错 2.数据库密码复杂度报错 3.数据库连接报错 四、总结 (1)概念 数据库管理系统(Database Management

    2024年02月12日
    浏览(69)
  • 初识mysql数据库之mysql数据库安装(centos)

    目录 一、卸载不需要的环境 二、安装mysql yum源 三、安装mysql 四、登录mysql 1. 直接登录 2. 设置免密码登录 五、配置my.cnf 六、mysql登录时的一些选项介绍 要注意,在安装mysql数据库时,最好将用户切换为root,避免一些不必要的问题。当数据库安装好后,普通用户也可以使用的

    2024年02月03日
    浏览(54)
  • MySQL笔记——MySQL数据库介绍以及在Linux里面安装MySQL数据库,对MySQL数据库的简单操作,MySQL的外接应用程序使用说明

    MySQL笔记——MySQL数据库介绍以及在Linux里面安装MySQL数据库,对MySQL数据库的简单操作,MySQL的外接应用程序使用说明 MySQL笔记——表的分组查询、表的分页查询、表的约束、数据库设计 MySQL案例——多表查询以及嵌套查询 MySQL笔记——数据库当中的事务以及Java实现对数据库进

    2024年01月16日
    浏览(80)
  • 【MySQL】使用DBeaver数据库管理工具进行MySQL数据库连接

    一、数据库连接信息填写 1、服务器地址:填写服务器部署的地址,以及端口号 2、数据库:sys 3、用户名:root 4、密码:服务器上面设置的具体密码 以上信息填写错误的报错提示 :Access denied for user ‘XXX’@’%’ to database ‘10.42.67.22’ 二、数据库说明 1、数据库连接时选择的

    2024年02月09日
    浏览(102)
  • MySQL示例数据库(MySQL Sample Databases) 之 sakila数据库

    官方示例数据介绍 MySQL 官方提供了多个示例数据库,在MySQL的学习、开发和实践中具有非常重要的作用,能够帮助初学者更好地理解和应用MySQL的各种功能和特性。 官方示例数据具体列表如下: 这些数据库都可以通过如下官方网址进行下载和安装 sakila数据库 可以在MySQL官方

    2024年02月05日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包