mysql innodb缓存策略之Buffer Pool

34 篇文章 3 订阅
27 篇文章 0 订阅

The InnoDB Buffer Pool

   Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb bufferpool怎么工作,和利用它读取频繁访问的数据,是mysql优化重要的方面。

   理想状况下,把bufferpool的大小调整到足够大,留下足够的内存空间给其他该服务器上的进程(使其无缺页即可)。bufferpool越大,innodb 月表现为内存型数据库,从硬盘上一次读取数据,之后并成了从内存中读取数据。buffer pool甚至缓存那些因为insert,update操作而改变的数据(insert buffer),所以随机磁盘写可以聚集在一块得到更好的性能。

   innodb 把缓存池作为链式管理,利用LRU(least recently used)算法,当添加新block到pool中时(无空间),innodb 替换(驱逐)一个最近最少使用的block,然后把新的block添加到链表的中间,"midpoint insertion strategy"策略把链表看出两条子链。

     1:在链表的头部,是由一些“NEW”(or "young")block 组成的最近刚被访问的子链;

     2:在链表的尾部,是由一些'old' block组成的最近没被访问(或者最少被访问的)的子链;

 

 该算法使大量查询 blocks 保持在  new sublist. old sublist 持有最少使用的 blocks;这些blocks将成为替换或驱逐的候选者。

     1:3/8 的buffer pool 的大小分配给old sublist

     2: 链表的 midpoint (中间插入点) 是new sublist 尾部和 old sublist头部聚合的地方

     3:当 innodb 读取一个block进 buffer pool时,插入到midpoint(old sublist 的头部),block被读取发生在 客户端操作,eg: sql查询,或者innodb特性 readahead(预读);

     4:当访问在old sublist中一个 block时,使其变成'young',把它移动到 buffer pool的头部(new sublist的头部),如果该block 被读取是因为客户端sql查询,则第一次访问立即发生,并且该block变成'young'。如果该block被读取是因为read ahead,第一次呗访问不会发生,并且有可能在该Block被替换之前根本不能发生);

     5:随着数据库操作,在buffer pool 中的没被访问的blocks(年纪大的)被移动到链表的尾部.在old sublist中的blocks 比插入在midpoint上的block老,最终,一个Block一段长时间未被使用会到达old sublist的尾部会被替换。

     默认情况下,被读取的blocks会立即移动到 NEW sublist 的 head,同时意味着他们待着buffer pool中很长一段时间。当扫表时(eg, mysqldump 操作,或者 没有where语句的select操作 )可以使大量的blocks  push into buffer pool中,并且驱逐大量的older 数据,即使那些所谓刚加入的 new blocks 不会再次被访问,相同的,read ahead 后台线程一次载入大量的blocks  ,这些情况使经常被访问的blocks push into 到 old sublist中,然后它们成为被驱逐的候选者。

  一些innodb 系统变量控制着buffer pool的大小和使你调整LRU算法

    1:innodb buffer pool size

       指明Buffer pool的大小,如果你的buffer pool 空间小,并且有充足的空间,使pool大点可以减小磁盘IO的次数来提高性能;

/* If the default value of innodb_buffer_pool_size is increased to be more than
BUF_POOL_SIZE_THRESHOLD (srv/srv0start.cc), then srv_buf_pool_instances_default
can be removed and 8 used instead. The problem with the current setup is that
with 128MiB default buffer pool size and 8 instances by default we would emit
a warning when no options are specified. */
// 128MiB / 8 = 16KB
static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, srv_buf_pool_curr_size,
                             PLUGIN_VAR_RQCMDARG |
                                 PLUGIN_VAR_PERSIST_AS_READ_ONLY,
                             "The size of the memory buffer InnoDB uses to "
                             "cache data and indexes of its tables.",
                             NULL, innodb_buffer_pool_size_update,
                             static_cast<longlong>(srv_buf_pool_def_size),
                             static_cast<longlong>(srv_buf_pool_min_size),
                             longlong{srv_buf_pool_max_size}, 1024 * 1024L);

innodb_buffer_pool_size的大小默认是128MB,分为8个instance,每个instance是16KB,并且对数据的操作是按页进行读写的,一页就是16KB。

    buffer_pool是一个list,目的是为了使用LRU cache机制;减少并发写操作时锁的粒度。

2: innodb buffer pool instances : 分成多个独立的区域,各个区域相同,来减少在并发内存读写操作的竞争;

    3:innodb old blocks pct:默认3/8;

    4:  innodb old blocks time: 指定多长时间以毫秒为单位(ms),block插入到老子列表必须呆在那里第一次访问后多久,才能搬到新的子列表(解决预读时,缓存污染问题);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值