14.5.2 Change Buffermysql
14.5.4 Log Buffer
3:首先来看BufferPoolsql
那数据在buffer里是怎么存储的呢? 在看官方给的架构图
先不细分析这个结构,大体看了下就是使用了LRU(least recently used 这个你们都很熟悉吧.不熟悉自行补充)算法. 而且把整个列表分了new和old两部分. 还有一点就是列表里每一项到底缓存数据的维度是什么?因此下面将分3个部分介绍 1:buffer pool 缓存的数据维度是什么? 2:为何LRU算法还有new和old部分,为何会这样涉及? 3:实战看下buffer pool相关的部分
1:buffer pool 缓存的数据维度是什么?
When room is needed to add a new page to the buffer pool, the least recently used page is evicted and a new page is added to the middle of the list. 从官方这句话,咱们能够得知每一项都是一页数据 . 这个后期写mysql索引文章的时候,会详细分析为何会是页数据为单位.
2:为何LRU算法还有new和old部分,为何会这样设计?数据库
其实你们想一想只有LRU算法的缺点就知道了. 看下图
就是随着新的数据页进来,列表中的数据会被大量置换出去. 没有达到缓存的目的. 其实官方也介绍了哪些状况下会出现这种状况[见下图].
说白了,全表扫描,什么mysqldump操做,select语句没有where条件,都会把大量数据放进buffer bool,即时这些数据并非热点数据, 但同时还会把热点数据给排挤出去.
那增长了new和old部分,当出现上面操做,又是怎样保护热点数据呢?
可从上图看出,新读入的数据都放在old列表,而且不会替换掉new列表中的热点数据. 那问题来了,何时old列表中数据会进入new列表呢?
实际上是进入buffer pool的数据,能被真正读取到, 并停留必定时间窗口,才会进入new列表 [有点像jvm内存分代,多大年龄能够进入老年代].缓存
其实真实的状况是: 首先mysql会预读数据 [局部性原理,你们能够自行了解] 另外加上上面说的全表扫描 mysqldump等. 这两种状况, 使进入的buffer pool中的数据并不必定被读到, 因此不能直接把热点数据给置换掉,才弄出来new列表和old列表,而且old列表的数据被访问到,且经历过T时间[时间窗口] 才会进入new列表.服务器
3:实战看下buffer pool相关的部分数据结构
窗口执行 show variables like '%buffer_pool%';
好像看不太懂,仍是从buffer pool的数据结构反推应该有哪些配置吧.架构
能够看到有好多字段, 但有个POOL_ID=0 可见我本地就一个缓冲池.jvm
innodb_old_blocks_pct表明old列表的大小,范围[5,95] 其余本身到官网看吧.
innodb_old_blocks_time=1000 默认1s
综合innodb_old_blocks_pct和innodb_old_blocks_time 有两种状况
若是业务中常常出现表扫描, 这时候就该把innodb_old_blocks_pct调小, 把innodb_old_blocks_time调大,避免不少预读的数据进入缓冲区.
若是业务中没有大量的表扫描. 这时候就该把innodb_old_blocks_pct调大,把innodb_old_blocks_time减少,让热点数据尽快进入new列表.减小磁盘io,提升性能.
INNODB_BUFFER_PAGE
INNODB_BUFFER_PAGE_LRU
先看第一张表:INNODB_BUFFER_PAGE 如今明白了 其实就是缓冲池中的全部的页信息.
在来看第二张表INNODB_BUFFER_PAGE_LRU
实际上是LRU列表中的页信息. 从这里咱们能够得出,BUFFER POOL 中不只仅只有一个LRU列表,还有其余缓存信息.
HIT_RATE:表示命中率 不用说,越高越好.
PAGES_MADE_YONG: 这个是从old列表到new列表的数量。
另外咱们发现: FREE_BUFFERS: 7704
DATABASE_PAGES: 487 POOL_SIZE: 8191
7704+487=8191; 可见buffer_pool 中除来一个lru列表[目前是DATABASE_PAGES] 还有一个FREE_BUFFERS缓存. 其余的缓存咱们下一次在一一分析.