14.4.3.3 Making the Buffer Pool Scan Resistant 让Buffer Pool 扫描
相比使用一个严格的LRU算法, InnoDB 使用一个技术来最小化数据的总量,带入到buffer pool
不会被再次访问。
目的是确保频繁访问的("hot") 页停留在buffer pool里,
即使 预读和全表扫描把新的blocks 可能或者可能之后不被访问了。
新的读取的块被插入到LRU列表的中部,所有新读取的pages 是被插入到默认是 从LRU 列表尾部 3/8的位置。
pages 会被移动到列表的前面( 最近使用的尾端)
当它们在buffer pool被第一次访问。
因此,pages 不再被访问 不会让它到LRU 列表的全面部分,会很快淘汰 相比一个严格的LRU 方法。
这种安排 将LRU 列表氛围两端,pages插入点的中下游是认为老的,会被LRU驱逐
你可以控制插入点再LRU 列表和选择是否InnoDB 应用相同的优化对于带入到buffer pool的blocks.
配置参数是innodb_old_blocks_pct 控制 old blocks 的比例在LRU列表。
默认innodb_old_blocks_pct 是37,对应的固定比率是3/8.
mysql> show variables like '%innodb_old_blocks_pct%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_old_blocks_pct | 37 |
+-----------------------+-------+
1 row in set (0.00 sec)
值的范围是5(new pages 在buffer pool 会被很快淘汰) 到95(只有5%的buffer pool 会保留对于热pages)
,
使得算法更接近于熟悉的LRU策略)
优化 让buffer pool 避免搅动 被预读可以避免类似问题由于 表或者索引扫描。
在那种扫描下,一个数据page 是典型的被访问很少次 在一个快速替代
不会再次访问。
配置参数是 innodb_old_blocks_time 指定时间(毫秒) 在第一次访问到page ,可以被访问不需要移动到
LRU 列表的最前面( 最近使用列表的最后面)
默认的innodb_old_blocks_time 是1000, 增加这个值可以让越来越多的块可能更快的age out 从buffer
pool
由于这些参数的影响可以广泛的基于你的硬件配置,你的数据,和你负载的细节,
总是参照来验证有效性 在你改造这些设置 在生产环境。
innodb_old_blocks_pct and innodb_old_blocks_time 是动态的,global 可以在MySQL 选项文件指定
或者使用SET GLOBAL命令, 改变设置需要SUPER 权限
由于那些参数的影响可以。
在混合负载 大多数的活动是OLTP类型 定期的批量报告查询 会导致大量的扫描,
设置innodb_old_blocks_time 值在批处理运行可以帮助
mysql> show variables like '%innodb_old_blocks_pct%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_old_blocks_pct | 37 |
+-----------------------+-------+
1 row in set (0.00 sec)
当扫描大表,不能把整个放到buffer pool里时, 设置innodb_old_blocks_pct 为一个小的值
可以 让那些只读一次 消耗buffer pool的很大一部分。
比如,可以设置innodb_old_blocks_pct=5 可以限制那些只读一次的数据 到buffer pool的5%
当扫描小表到buffer pool, 移动pages 负载较小,你可以innodb_old_blocks_pct 为默认值,甚至更大
比如innodb_old_blocks_pct=50.