开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,在新加的朋友会分到2群(共740人左右 1 + 2)
你是否可以想象如果MYSQL 没有了innodb_buffer_pool 是什么样子的情况,本期需要说说MYSQL的缓存,已经如何使用他更加有效用或者说性价比。首先MYSQL 使用缓存机制的目的是什么?
减少磁盘访问的频率,提高数据访问效率是缓冲存在的基础目的,而一般的情况下,数据库所在的服务器的内存很难HOLD住所有的在服务器上存在的数据,所以缓存是珍贵的,那么珍贵的基础上如何更有效的利用缓存就是一个特别重要的部分。
这里通过直接从内中提供数据页面的数量和对比从磁盘需要读入的数据页面的数量,和在某一个时刻缓存中被驱逐的页面,来去评判缓存的运行效率是一种常见的方式。
MYSQL中其标准InnoDB存储引擎的主要数据缓存结构称为Buffer Pool。暴露Buffer Pool效率的两个状态变量(或在本例中的状态计数器)如下所述(引用MySQL手册):
Innodb_buffer_pool_read_requests:逻辑读请求的数量。
Innodb_buffer_pool_reads:InnoDB无法满足缓冲池的逻辑读取数,必须直接从磁盘读取的逻辑读取数。
MYSQL 中可以通过percona 公司的pt 工具来捕捉这些数据的动态量,用来分析服务器的性能。如pt-stalk 来统计某一个时间段的变量值。
pt-stalk --no-stalk --iterations=1
具体的pt_stalk 的使用可以参考percona 官方的文档,进行详细的参数了解和使用。
提到这里,很多人会想起buffer hit ratio 这个问题,很多同学通过这个指数来标定当前的缓冲是否够用。一般的观点是如果buffer hit ratio 的低于95% - 99% (我听到过大多数DBA的观点。也有个别的提高过90%)这个标准后说明缓存不足以支撑当前的数据库的使用。
如果单独拿出来这个观点来,将其他的可能性都不考虑的情况下,这个观点是正确的,的确是缓冲不足以支撑当前的查询。但我们应该下探如下的部分来去解决问题,而不是直接添加更大的物理内存和提高innodb_buffer pool 的配置。
1 是否是由于磁盘的问题导致,如磁盘的速度较慢,而导致在提取数据时导致的数据提取时间过长导致的问题
2 是否是由于没有有效的索引导致的,全表扫描引起的所谓的 buffer_hit_ratio 较低导致的问题
3 使用MYSQL 作为OLAP 的使用方式导致的 buffer_hit_ratio 数值较低的问题。
除此以外,是缓冲本身的大小的设置问题,或真的是物理内存交付的不合理的问题等等。
那么缓冲不足可能会造成什么问题也是我们需要进行了解和学习的,缓冲不足
查看缓冲命中率语句方式
SELECT variable_value INTO @num_reads
FROM performance_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_read_requests';
SELECT variable_value INTO @num_misses
FROM performance_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_reads';
SET @buffer_pool_size = (SELECT @@innodb_buffer_pool_size);
SELECT CONCAT(100 - ((@num_misses / @num_reads) * 100), '%') AS `Hit Ratio`;
同时还有相关的参数需要查看设置的是否合理,如innodb_lru_scan_depth, 他主要用于缓冲中每秒对于LRU中的脏页被扫描的深度问题, innodb 存储引擎中,LRU 链表用于管理缓冲池中的页面,当脏页达到一定的程序就需要清理出内存,innodb_lru_scan_depth 可以控制innodb 存储引擎在扫描LRU链表对于脏页进行flush 的速率和频率,从而更好的平衡内存的资源,与IO 性能之间的关系。
这个值在 0 - 1024 ,更小的值会减少扫描的深度,延缓脏页刷回到磁盘的速度,降低磁盘的压力,如果你的内存较大,并且有频繁的访问,同时还都是类OLAP的访问方式,如果此时磁盘的压力较高,并且忽高忽低,可以将这个参数调低,并观察,找到平衡点。