专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

MySQL buffer pool 学习笔记

学习了小青蛙老师的文章。总结一下吧。
MySQL的数据都是存放在磁盘中,而磁盘的读写又是非常慢的,因此为了加快数据访问速度,MySQL会把数据放在缓存里,这个缓存就是buffer pool(缓冲池)
#缓冲池是是什么
是MySQL服务器启动时向内存申请的一块连续的空间,可以使用下面的语句查看MySQL申请的空间大小,

show variables like 'innodb_buffer_pool_size';

我这里是134217728字节,也就是128M。

innodb_buffer_pool_size | 134217728

#如何管理
MySQL会维护一个free链表,记录的是当前buffer pool里空闲的页。每当有新的页进来的时候,先看有没有剩余空间,有的话直接从free链表申请一页放下,同时把这页从free链表删掉。

  • 所以每次MySQL读取一页的时候,会先到缓冲池中查找该页是否在缓冲池中,在的话直接拿。查询是否在的话利用的是哈希,用表空间+页号作为key,对应的页作为value,就可以很快的判断某页是否在缓冲池中了。

#缓存页的替换
MySQL缓存页的替换也是用了大名鼎鼎的LRU算法,即最近最少使用。会把最近使用次数最少的替换出去。
不过MySQL也不是简单的使用LRU。而是做了一些改变。

#为何改变
由于有下面两个问题,所以MySQL对LRU做了一些改变:

  • 预读失效
    由于预读,把一些页提前放到了缓冲池,但是最终MySQL并没有从页中读取数据
  • 缓冲池污染 由于某些操作需要扫描全表,这样每次操作都会把缓冲池的数据全部替换一遍,会严重影响其他查询对缓冲池的使用,大大降低缓存命中率。 比如以下语句
select * from user where name like '%三%';

因为like不能命中索引,必须全表扫描,会访问到大量的页。

  • 首先把页加到缓冲池中,查到old区域头部;
  • 从页里读数据(会被放到young区域头部)
  • row里比较,符合条件就加到结果集
  • 直到扫描完所有页中的row. 所有的页都会被加到young区域头部,但是只会访问一次,真正的热数据被大量替换走了。 可以结合这里理解:mp.weixin.qq.com/s/nA6UHBh87…

#如何改变

把LRU链表分成了两部分,一部分是young区域,一部分是old区域。两部分各占的比例可通过下面的语句查询,比如我这里查询到的是old区域占比37%。

SHOW VARIABLES LIKE 'innodb_old_blocks_pct';
| innodb_old_blocks_pct | 37    |

  • 针对预读失效问题,某个页首次从磁盘加载到缓冲池的时候,会首先放到old区域的头部,如果之后这些页面没有被读取使用,最终会从old区域尾部剔除。如果被读取(预读成功),才会加到young区域头部。
  • 针对缓冲池污染问题,某个页首次从磁盘加载到缓冲池的时候,会首先放到old区域的头部,即使立刻被访问,并不会马上放到young区域头部,只有满足被访问并且在old区域停留时间大于T的 才会被放入young区域。
    这里的T可以通过下面的语句查看,我这里默认设置的是1000ms。
SHOW VARIABLES LIKE 'innodb_old_blocks_time';
| innodb_old_blocks_time | 1000  |

文章永久链接:https://tech.souyunku.com/45210

未经允许不得转载:搜云库技术团队 » MySQL buffer pool 学习笔记

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们