由于硬盘和内存的造价差异,一台主机实例的硬盘容量通常会远超于内存容量。对于数据库等应用而言,为了保证更快的查询效率,通常会将使用过的数据放在内存中进行加速读取。

数据页与索引页的LRU

数据页和索引页的目的在于缓存一部分的表数据和索引数据,其数据总量通常会超过缓冲池大小,所以缓冲池中应只缓冲那些经常使用的热点数据。InnoDB内存管理使用的是最近最少使用(Least Recently Used, LRU)算法。来淘汰最久未使用的数据。

InnoDB Buffer Pool改进LRU页面置换-LMLPHP

在一般的LRU算法中,当链表中的某一个数据被读取时,将会将其放置于队首。当新增数据且链表已达最大数量时,将链表尾部的数据移除,并将新增的数据置于链表首部。

InnoDB的LRU并没有使用传统的双端链表,而是做了改进,这里有两个问题:

  • 预读失效
  • 缓冲池污染

优化预读失效

由于预读(Read-Ahead),提前把页放入了缓冲池,但最终 MySQL 并没有从页中读取数据,称为预读失效。

Read-Ahead机制

Read-Ahead用于异步预取buffer pool中的多个page的一个预测行为。

InnoDB使用两种提前预读Read-Ahead算法来提高I/O性能。

  • Linear read-ahead 线性预读

如果一个extent中的被顺序读取的page超过或者等于   innodb_read_ahead_threshold  参数变量时,Innodb将会异步的将下一个extent读取到buffer pool中,innodb_read_ahead_threshold可以设置为0-64的任何值(注:innodb中每个extent就只有64个page),默认为56。值越大,访问模式检查就越严格。

  • Random read-ahead 随机预读

如果当同一个extent中连续的13个page在buffer pool中发现时,Innodb会将该extent中的剩余page读到buffer pool中。控制参数  innodb_random_read_ahead  默认没有开启。

 

如何对预读失效进行优化?
03-30 17:17