MySQL_内存

MySQL_内存

Buffer Pool

目的:提高数据库的读写性能。
位置:在InnoDB存储引擎中。

读、改数据的顺序:

  1. 数据如果在Buffer Pool中,客户端直接读取Buffer Pool中的数据,否则去磁盘中读取。
  2. 修改数据时,先修改Buffer Pool中数据所在的页16KB,将其设置为脏页,最后由后台线程将脏页写入到磁盘。

缓存什么:
索引页、数据页、插入缓存、undo页、自适应哈希索引、锁信息。

怎么管理:
InnoDB为每一个缓存页都创建了一个控制块,包括(缓存页的表空间,页号,缓存页地址,链表节点等等)
控制块的位置:在Buffer Pool的最前面,接着才是缓存页。

如何管理Buffer Pool

如何管理空闲页

Free链表(空闲链表):将空闲缓存页的控制块作为链表的节点。
Free链表还有一个头节点,包含(链表的头节点地址,尾节点地址,当前链表中节点的数量等信息)
提高了读性能。

如何管理脏页

Flush链表:链表元素都是脏页。
提高了写性能。

如何提高缓存命中率

改进版LRU算法。
Buffer Pool中有3种页和链表管理数据:

  1. Free Page,位于Free链表。
  2. Clean Page,位于LRU链表。
  3. Dirty Page,同时位于LRU链表和Flush链表。(刷盘后,就变成了Clean Page,所以位于LRU链表)

普通LRU算法的问题:

  1. 预读失败。(MySQL加载数据页时,会提前把它相邻的数据页一并加载进来,目的是为了减少磁盘IO)预读失败就是被提前加载进来的数据页,并没有被访问。
    解决:LRU分成2部分(old区域和young区域)(innodb_old_blocks_pct可以设置old-young比例)预读的页只加入old区域的头部,页真正被访问(读取页里的记录)的时候,才将页插入young区域的头部。
  2. Buffer Pool污染。一个SQL语句扫描了大量的数据时,Buffer Pool种所有的页都替换出去,导致大量热数据被淘汰了。(比如全表扫描)
    解决:old进入young的条件增加一个停留在old区域的时间判断。大于这个时间间隔innodb_old_blocks_time才放入young区域。
脏页什么时候刷盘

WAL技术,先写日志,再刷盘。

  1. redo loh日志满了。
  2. Buffer Pool空间不足。淘汰一部分数据页,如果淘汰的是脏页,则刷盘。
  3. MySQL认为空闲时,后台线程刷盘。
  4. MySQL正常关闭之前。
三种List总结
  1. Free List 管理空闲页
  2. Flush List 管理脏页
  3. LRU List 管理脏页+干净页。
posted @   Espre-sso  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示