MySQL InnoDB引擎的缓存特性详解

 更新时间:2022年09月13日 08:41:31   作者:Amos01  
这篇文章主要介绍了MySQL InnoDB引擎的缓存特性详解的相关资料,需要的朋友可以参考下

1. 背景

对于各种用户数据、索引数据等各种数据都是需要持久化存储到磁盘,然后以“页”为单位进行读写。

相对于直接读写缓存,磁盘IO的成本相当高昂。

对于读取的页面数据,并不是使用完就释放掉,而是放到缓冲区,因为下一次操作有可能还需要读区该页面。

对于修改过的页面数据,也不是马上同步到磁盘,也是放到缓冲区,因为下一次有可能还会修改该页面的数据。

但是缓存的空间是有大小限制的,不可能无限扩充。

对于缓冲区的数据,需要有合理的页面淘汰算法,将未来使用概率较小的页面释放或者同步到磁盘,

给当下需要存放到缓存的页面腾出位置。

2. 存储器性能差异

寄存器:CPU暂存指令、数据的小型存储区域,速度快,容量小。

CPU高速缓存(CPU Cache):用于减少CPU访问内存所需平均时间的部件。

内存:用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。

硬盘:分为固态硬盘(SSD)和机械硬盘(HHD),是非易失性存储器。

下图是各种缓存器的价格和性能差距,

从下图可以看出,SSD的随机访问延时在微妙级别,而内存的的随机访问延时在纳秒级别,内存比SSD大概快1000倍左右。

3. Buffer Pool

一个缓冲池(缓冲池)是向操作系统申请的一块内存空间,这块内存空间由多个chunk组成,每个chunk均包含多个控制块和对应的缓冲页。

chunk是向操作系统申请内存的最小单位,缓冲页大小与InnoDB表空间使用的页面大小一致。

Buffer Pool的示意图如下

每一个控制块都对应一个缓冲页,控制块包含该缓冲页所属的表空间编号、页号、在Buffer Pool中的地址、链表结点信息等等。

当刚读取一个页面时,需要知道缓冲区有哪些空闲页面,当修改过后缓冲页后,需要记录该缓冲页需要持久化到磁盘,

当缓冲区没有空闲页面了,需要有页面淘汰算法来将缓冲页移出缓冲区,

以上涉及到Free链表、Flush链表、LRU链表,下面注意说明。

4. Free链表

Free链表是由空闲的缓冲页对应的控制块组成的链表,通过Free链表就获取到空闲的缓冲页及其在缓冲区中的地址。

每当需要从磁盘加载一个页面到缓冲区时,从该Free链表取出一个控制块结点,从Free链表移除该结点,并加入LRU链表。

如果这个缓冲区页面被修改过,那么会被加入到Flush链表中。

5. Flush链表

如果一修改缓冲页的数据之后就刷新到磁盘,这种频繁的IO操作势必影响程序等整体性能。

试想一下,先后修改1000次同一缓冲区页面的一字节数据,每次修改都刷新到磁盘,与修改1000次后再将最终结果刷新磁盘,节省了999次刷新磁盘的操作。

因此,当页面的数据被修改之后,需要将改页面放到Flush链表,排队等候写入磁盘。

这既可以减少在用户进程中刷新磁盘的次数,也从整体上减少了磁盘IO到次数。

6. LRU链表

内存空间有限,不可能将所有数据都缓存在内存当中,因此需要有一定的算法将内存中页面淘汰掉(修改过的页面持久化到磁盘)。

LRU(Least Recently Used)链表主要用于辅助实现内存页面淘汰,故名思义,最先淘汰的是最近最少使用的缓冲页。

LRU链表的结果如下图所示

将LRU链表分为young区域和old区域。

对于初次加载到缓冲区的页面,会放到LRU链表old区域的头部,这主要避免了预读的页面被放到了LRU链表的首部。

当第二次访问缓冲页且时间间隔超过innodb_old_blocks_time(默认1s)时,才将该页面移动到LRU链表的首部。

进一步,为了避免频繁的移动链表结点,当某个缓冲页已经在young区域的前3/4时,则不会移动该结点到首部。

7. 其它

如何定位页面是否被缓冲呢?

表空间号和页号可以唯一识别缓冲页,因此InnoDB引擎建立了以表空间号+页号为key,以缓冲页控制块地址为value的哈希表,

从而快速判断页面是否被缓冲,快速定位到数据所在地址。

到此这篇关于MySQL InnoDB引擎的缓存特性详解的文章就介绍到这了,更多相关MySQL InnoDB 缓存特性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Mysql触发器语法解读(附带简单实用例子)

    Mysql触发器语法解读(附带简单实用例子)

    这篇文章主要介绍了Mysql触发器语法解读(附带简单实用例子),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Mysql5.5安装配置方法及中文乱码的快速解决方法

    Mysql5.5安装配置方法及中文乱码的快速解决方法

    这篇文章主要介绍了Mysql5.5安装配置方法以及mysql5.5中文乱码的快速解决方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-08-08
  • mysql自动插入百万模拟数据的操作代码

    mysql自动插入百万模拟数据的操作代码

    这篇文章主要介绍了mysql自动插入百万模拟数据的示例代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • mysql利用参数sql_safe_updates限制update/delete范围详解

    mysql利用参数sql_safe_updates限制update/delete范围详解

    这篇文章主要给大家介绍了关于mysql如何利用参数sql_safe_updates限制update/delete范围的相关资料文中介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-10-10
  • MySQL使用UNIQUE实现数据不重复插入

    MySQL使用UNIQUE实现数据不重复插入

    当unique列在一个UNIQUE键上插入包含重复值的记录时,我们可以控制MySQL如何处理这种情况:使用IGNORE关键字或者ON DUPLICATE KEY UPDATE子句跳过INSERT、中断操作或者更新旧记录为新值。
    2017-05-05
  • spark rdd转dataframe 写入mysql的实例讲解

    spark rdd转dataframe 写入mysql的实例讲解

    今天小编就为大家分享一篇spark rdd转dataframe 写入mysql的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-06-06
  • MySQL占用内存较大与CPU过高测试与解决办法

    MySQL占用内存较大与CPU过高测试与解决办法

    为了装mysql环境测试,装上后发现启动后MySQL占用内存了很大,达8百多兆。网上搜索了一下,得到高人指点my.ini。再也没见再详细的了..只好打开my.ini逐行的啃,虽然英文差了点,不过多少M还是看得明的
    2018-03-03
  • MySql通过ip地址进行访问的方法

    MySql通过ip地址进行访问的方法

    这篇文章主要介绍了MySql通过ip地址进行访问的方法,首先要登录mysql,切换数据库然后授权,具体代码详情大家参考下本文
    2018-06-06
  • mYsql日期和时间函数不求人

    mYsql日期和时间函数不求人

    mYsql日期和时间函数不求人...
    2007-04-04
  • MySQL修改innodb_data_file_path参数的一些注意事项

    MySQL修改innodb_data_file_path参数的一些注意事项

    这篇文章主要给大家介绍了关于MySQL修改innodb_data_file_path参数的一些注意事项,文中通过示例代码介绍的非常详细,对大家学习或者使用MySQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04

最新评论