Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Making the Buffer Pool Scan Resistant

17.8.3.3 缓冲池扫描抵抗

而不是使用严格的LRU算法,InnoDB 使用了一种技术来最小化缓冲池中从未访问过的数据量。目标是确保频繁访问()页面在缓冲池中保持, 即使读前全表扫描将新块带入缓冲池中,这些块可能或可能不被访问。

新读取的块插入LRU列表的中间。所有新读取的页面都插入默认在LRU列表的末尾的3/8处。这些页面在第一次从缓冲池中访问时被移动到列表的前端(最近使用的结尾)。因此,从未访问过的页面永远不会出现在列表的前端部分,并且淘汰更快地淘汰,而不是使用严格LRU方法。这一安排将LRU列表分成两个部分,其中下游插入点以下的页面被认为是,并且是LRU淘汰的可取目标。

关于InnoDB缓冲池的内部工作和LRU算法的详细信息,请见第17.5.1节,“缓冲池”

您可以控制LRU列表中的插入点,并选择是否将InnoDB应用于由表或索引扫描带入缓冲池的块。配置参数innodb_old_blocks_pct控制LRU列表中的“old”块百分比。默认值为innodb_old_blocks_pct375(缓冲池中的新页面会很快被淘汰)到95(只保留5%的缓冲池用于热页,使算法接近LRU策略)。

避免读取前导优化可以避免由表或索引扫描引起的问题。在这些扫描中,数据页面通常在快速 succession访问一次,然后再无需访问。配置参数innodb_old_blocks_time指定了在首次访问页面后可以访问该页面的时间窗口(以毫秒为单位)。默认值为innodb_old_blocks_time1000。增加该值使更多和更多块更快地从缓冲池中淘汰。

Both innodb_old_blocks_pctinnodb_old_blocks_time 可以在 MySQL 选项文件 (my.cnfmy.ini) 中指定或在运行时使用SET GLOBAL 语句更改。更改值需要具有足够的权限以设置全局系统变量。请参阅第7.1.9.1节,“系统变量权限”

为了帮助您评估这些参数的影响,SHOW ENGINE INNODB STATUS 语句报告缓冲池统计信息。详细信息请参阅使用 InnoDB 标准监控器监控缓冲池

由于这些参数的影响取决于您的硬件配置、数据和工作负载的细节,因此在任何性能关键或生产环境中更改这些设置之前,总是要进行基准测试以验证其有效性。

在混合工作负载中,其中大多数活动是 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无法获得足够的性能改进,请进行自己的 benchmarks以确定最优值。