• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 使缓冲池扫描具有抵抗性

    与其使用严格的LRU 算法,不如使用一种InnoDB技术来最小化被带入缓冲池并且永远不会再次访问的数据量。目的是确保经常访问的(“热”)页保留在缓冲池中,即使预读和全表扫描会引入新的块,这些块以后也可能不会访问。

    新读取的块将插入到LRU列表的中间。默认情况下,所有新读取的页面都插入3/8到LRU列表末尾的位置。当页面第一次在缓冲池中访问时,这些页面将移到列表的最前面(最近使用的末尾)。因此,从未访问过的页面永远不会进入LRU列表的前部,并且比严格的LRU方法更早地“老化”。这种安排将LRU列表分为两个部分,其中插入点下游的页面被认为是“旧的”,是LRU驱逐的理想受害者。

    有关InnoDB缓冲池内部工作的解释以及有关LRU算法的详细信息,请参见“InnoDB缓冲池”。

    您可以控制LRU列表中的插入点,并选择是否InnoDB对表或索引扫描带入缓冲池的块应用相同的优化。配置参数innodb_old_blocks_pct控制LRU列表中“旧”块的百分比。的默认值innodb_old_blocks_pct37,对应于3/8原固定比率。值的范围是5(缓冲池中的新页面很快老化)到95(仅5%的缓冲池留给热页面使用,这使得该算法接近于熟悉的LRU策略)。

    防止缓冲池被预读搅动的优化可以避免由于表或索引扫描而引起的类似问题。在这些扫描中,通常快速连续地访问数据页面几次,而再也不会被访问。配置参数innodb_old_blocks_time指定第一次访问页面后的时间窗口(以毫秒为单位),在该时间窗口内可以访问页面而不将其移到LRU列表的最前面(最近使用的末尾)。默认值innodb_old_blocks_time1000。增大此值会使越来越多的块从缓冲池中更快地老化。

    两者都可以在MySQL选项文件(或)中指定innodb_old_blocks_pctinnodb_old_blocks_time也可以在运行时使用语句进行更改。在运行时更改值需要足够的特权来设置全局系统变量。请参见“系统变量特权”。my.cnfmy.iniSET GLOBAL

    为了帮助您评估设置这些参数的效果,该SHOW ENGINE INNODB STATUS命令报告缓冲池统计信息。有关详细信息,请参阅使用InnoDB Standard Monitor监视缓冲池。

    由于这些参数的影响可能会因您的硬件配置,数据和工作负载的详细信息而有很大差异,因此在任何对性能至关重要的环境或生产环境中更改这些设置之前,请始终进行基准测试以验证有效性。

    在大多数活动是OLTP类型的混合工作负载中,使用定期批处理报告查询会导致较大的扫描,innodb_old_blocks_time在批处理运行期间设置的值可以帮助将正常工作负载的工作集保留在缓冲池中。

    当扫描不能完全容纳在缓冲池中的大表时,将其设置innodb_old_blocks_pct为较小的值可以使仅读取一次的数据不会占用很大一部分缓冲池。例如,设置innodb_old_blocks_pct=5将只能读取一次的数据限制为缓冲池的5%。

    扫描适合内存的小表时,在缓冲池中移动页面的开销较小,因此您可以保留innodb_old_blocks_pct其默认值,甚至更高,例如innodb_old_blocks_pct=50

    innodb_old_blocks_time参数相比,innodb_old_blocks_pct参数的效果更难预测,相对较小,并且随工作负载而变化更大。要获得最佳值,如果调整带来的性能提升innodb_old_blocks_pct不足,请执行自己的基准测试。