• mysql-buffer pool


    数据都是存储在磁盘中的,单查询某条记录的时候,mysql从表空间中取出对应的页,从磁盘加载到内存,当查询完不会立刻释放,而是缓存起来.

    这个用于缓存磁盘中的页的连续内存空间就是buffer pool,可以在配置文件中设置大小默认128m

    buffer pool内部是由控制块缓存页组成

    控制块:保存着缓存页的属性控制信息

     当我们需要存储磁盘页的时候需要知道存到哪个缓存页中,我们如何知道那个缓存页是空的呢?

    free链表 mysql使用一个链表 来存储着空闲的缓存页,链表的基节点保存着链表的相关信息,mysql会创建一个hash表存储key 表空间号+页号 value为缓存也 方便使用缓存

    flush链表 修改过某个缓存页 对应的控制块都放入到这个链表中 方便某个时机写回磁盘 跟free链表一样有一个基节点

    毕竟buffer pool的空间是有限的,作为一个缓存来说就面临着淘汰缓存,mysql的lru算法是什么呢? 

    这个面临着两个问题:

    1. innodb有个预读的功能,线性预读如果顺序访问了某个区的页超过了innodb_read_ahead_threshold值, 将异步将这个区的页全部加载到buffer pool中 这个值默认56,

    随机预读如果buffer pool中存储着一个区的13个页面,就把这个区的页异步加载到buffer pool中 加载的页被放到链表的前面,如果预加载的页不是被频繁用到,当需要淘汰的时候就被链表后面需要被频繁用到的删除了

    2. 全表扫描把这个表所有的页加载到buffer pool ,频繁的执行全表操作,就会频繁将用不到的页加入buffer pool中,淘汰那些使用频繁的页了

    lru链表 为了解决这两点问题,mysql把lru链表分两个部分,一个存储使用频繁的页称为old页也叫热数据,一个存储使用频率没那么高的页称为young页也叫冷数据

    数据先被存入到old部分的头部,第一次访问处于old区域的页在对应的控制器加一个访问时间,后续访问计算访问间隔,若时间间隔超过系统设定的时间范围就把这个页移到young区域,young区的页再被访问处于young区后1/4的控制块才会提到lru链表young区的头

    这不是全部的lru策略,如果想了解更多请去看看源码哈~

    刷新脏页到磁盘

    mysql后台会每隔一段时间会刷新脏页到磁盘

    那么这个刷新策略是什么呢?

    buf_flush_lru 定时从lru链表尾部刷新一些脏页到磁盘

    buf_flush_list 定时从flush链表刷新一些脏页到磁盘

    当后台刷新速率比较慢,导致缓存页没有空余空间,会查看lru链表尾部是否有未修改过的页有的话就舍掉,如果没有就同步刷新lru尾部的一个脏页到磁盘

     为了处理多线程高并发,mysql把buffer pool分成多个实例,每隔个例由chunk组成

    上图是有两个buffer pool实例 每个实例有两个chunk区域(连续的内存空间)

    SHOW ENGINE INNODB STATUSG 使用这个命令查看buffer pool信息
  • 相关阅读:
    【git】git常用命令
    使用ssh脚本建立grid,oracle用户互信
    12.2地区,国家设置错误,导致乱码
    存储问题
    TFA卸载
    exp-00030 exp-00002
    ORA-03113错误
    Oracle 10g误删除数据文件
    查询10g数据库生产用户
    查看回话资源消耗情况
  • 原文地址:https://www.cnblogs.com/isnotnull/p/14446524.html
Copyright © 2020-2023  润新知