| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> MySQL: 14 LRU链表在Buffer Pool实际运行中可能导致的问题 -> 正文阅读 |
|
[数据结构与算法]MySQL: 14 LRU链表在Buffer Pool实际运行中可能导致的问题 |
1. LRU链表在Buffer Pool的应用Buffer Pool在使用过程中如果缓存页都使用了,没有空闲的缓存页时,可以去LRU链表中的尾部找一个最近最少使用的缓存页,把它的数据刷入磁盘,腾出来一个空闲缓存页,然后加载需要的新的磁盘数据页到空闲缓存页里去。 LRU链表的机制,只要是刚从磁盘上加载数据到缓存页里去,这个缓存页就放入LRU链表的头部,后如果对任何一个缓存页的访问,都会把缓存页从LRU链表中移动到头部去。 这样在LRU链表的尾部,一定是最近最少被访问的那个缓存页。 2.LRU机制在实际运行中存在的隐患首先会带来的隐患是MySQL的预读机制,说的就是当你从磁盘上加载一个数据页的时候,他可能会把这个数据页相邻的其他数据页,也加载到缓存页里去。 举个例子,假设现在有两个空闲缓存页,然后在加载一个数据页的时候,连带着把它的一个相邻的数据页也加载到缓存里去了,正好每个数据页放入一个空闲缓存页。 实际上这里只有一个缓存页是被访问了的,另外一个通过预读机制加载的缓存页,并没有人访问,但由于LRU机制导致两个缓存页都在LRU链表的前面。 ?参照上图,假如没有空闲缓存页了,那么此时要加载新的数据页了,就需要从LRU链表的尾部把所谓的“最近最少使用的一个缓存页” 给拿出来,刷入磁盘。 这时候有个问题,那就是如果把上图中LRU尾部的那个缓存页刷入磁盘然后清空,那这是不合理的,因为它之前一直频繁被人访问,只不过在这一瞬间,被新加载进来的两个缓存页给占据了LRU链表前面的位置,尤其是第二个缓存页,它是通过预读机制加载进来的,并没有人去访问。 最合理的应该是把上图中LRU链表的第二个通过预读机制加载进来的缓存页给刷入磁盘和清空,因为它几乎没有被访问过。 3.触发MySQL预读机制的场景触发MySQL预读机制的情况有以下几种: (1)有一个参数是 innodb_read_ahead_threshold,它的默认值是56,意思是如果顺序的访问了一个区里的多个数据页,访问的数据页的数量超过了这个阈值,此时就会触发预读机制,把下一个相邻区中的所有数据页都加载到缓存里去。 (2)如果Buffer Pool里缓存了一个区里的13个连续的数据页,而且这些数据页都是比较频繁会被访问的,此时就会直接触发预读机制,把这个区里的其他的数据页都加载到缓存里去。 预读机制是通过参数 innodb_random_read_ahead 来控制的,它默认是OFF,也就是说这个规则是默认关闭的。 默认情况下,主要是第一个规则可能会触发预读机制,一下子把很多相邻里的数据页加载到缓存里去,这些缓存页如果一下子都放在LRU链表的前面,而且没有什么人访问的话,就会导致原来在缓存里的一些频繁被访问的缓存页在LRU链表的尾部。 从而导致这部分频繁被访问的缓存页给刷入磁盘和清空掉。 4. 全表扫描导致频繁被访问的缓存页被淘汰的场景另外一种可能导致频繁被访问的缓存页被淘汰的场景,那就是全表扫描。 所谓全表扫描,就是类似如下的SQL语句: SELECT * FROM USERS。这种语句没加任何一个where 条件,导致一下子把该表中所有的数据页,都从磁盘加载到Buffer Pool里去。 在全表扫描的场景下,会一下子把这个表的所有数据页都一一装入各个缓存页里去。此时可能LRU链表中排在前面的一大串缓存页,都是全表扫描加载进来的数据页。 这就会导致这次全表扫描过后,排在LRU链表头部的是几乎没用到的表里的数据的缓存页。 而在LRU链表的尾部,可能全都是之前一直被频繁访问的那些缓存页。 然后当你要淘汰一些缓存页腾出空间时,就会把LRU链表尾部一直被频繁访问的缓存页给淘汰掉了,而留下之前全表扫描加载进来的大量的不经常访问的缓存页。 5.总结在使用简单的LRU链表机制时,由于预读机制或全表扫描的机制,会导致一下子把大量未来可能不怎么访问的数据页加载到缓存里去,然后LRU链表的前面全部是这些未来可能不怎么被访问的缓存页。 而真正之前一直被频繁访问的缓存页可能都在LRU链表的尾部。 如果没有空闲缓存页的时候,就会导致把LRU链表尾部那部分频繁被访问的缓存页刷入磁盘、清空掉,以此来腾出空间。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 18:43:44- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |