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.