浅谈mysql innodb缓存策略

浅谈mysql innodb缓存策略:mysql

 

 The InnoDB Buffer Pool

   Innodb 持有一个存储区域叫作buffer pool是为了在内存中缓存数据和索引,知道innodb bufferpool怎么工做,和利用它读取频繁访问的数据,是mysql优化重要的方面。算法

   理想情况下,把bufferpool的大小调整到足够大,留下足够的内存空间给其余该服务器上的进程(使其完好页便可)。bufferpool越大,innodb 月表现为内存型数据库,从硬盘上一次读取数据,以后并成了从内存中读取数据。buffer pool甚至缓存那些由于insert,update操做而改变的数据(insert buffer),因此随机磁盘写能够汇集在一块获得更好的性能。sql

   innodb 把缓存池做为链式管理,利用LRU(least recently used)算法,当添加新block到pool中时(无空间),innodb 替换(驱逐)一个最近最少使用的block,而后把新的block添加到链表的中间,"midpoint insertion strategy"策略把链表看出两条子链。数据库

     1:在链表的头部,是由一些“NEW”(or "young")block 组成的最近刚被访问的子链;缓存

     2:在链表的尾部,是由一些'old' block组成的最近没被访问(或者最少被访问的)的子链;服务器

 

 该算法使大量查询 blocks 保持在  new sublist. old sublist 持有最少使用的 blocks;这些blocks将成为替换或驱逐的候选者。mysql优化

     1:3/8 的buffer pool 的大小分配给old sublist并发

     2: 链表的 midpoint (中间插入点) 是new sublist 尾部和 old sublist头部聚合的地方性能

     3:当 innodb 读取一个block进 buffer pool时,插入到midpoint(old sublist 的头部),block被读取发生在 客户端操做,eg: sql查询,或者innodb特性 readahead(预读);优化

     4:当访问在old sublist中一个 block时,使其变成'young',把它移动到 buffer pool的头部(new sublist的头部),若是该block 被读取是由于客户端sql查询,则第一次访问当即发生,而且该block变成'young'。若是该block被读取是由于read ahead,第一次呗访问不会发生,而且有可能在该Block被替换以前根本不能发生);

     5:随着数据库操做,在buffer pool 中的没被访问的blocks(年纪大的)被移动到链表的尾部.在old sublist中的blocks 比插入在midpoint上的block老,最终,一个Block一段长时间未被使用会到达old sublist的尾部会被替换。

     默认状况下,被读取的blocks会当即移动到 NEW sublist 的 head,同时意味着他们待着buffer pool中很长一段时间。当扫表时(eg, mysqldump 操做,或者 没有where语句的select操做 )可使大量的blocks  push into buffer pool中,而且驱逐大量的older 数据,即便那些所谓刚加入的 new blocks 不会再次被访问,相同的,read ahead 后台线程一次载入大量的blocks  ,这些状况使常常被访问的blocks push into 到 old sublist中,而后它们成为被驱逐的候选者。

  一些innodb 系统变量控制着buffer pool的大小和使你调整LRU算法

    1:innodb buffer pool size

       指明Buffer pool的大小,若是你的buffer pool 空间小,而且有充足的空间,使pool大点能够减少磁盘IO的次数来提升性能;

    2: innodb buffer pool instances : 分红多个独立的区域,各个区域相同,来减小在并发内存读写操做的竞争;

    3:innodb old blocks pct:默认3/8;

    4:  innodb old blocks time: 指定多长时间以毫秒为单位(ms),block插入到老子列表必须呆在那里第一次访问后多久,才能搬到新的子列表(解决预读时,缓存污染问题);

 

  检查查询缓存是否存在于你的MySQL服务器:

mysql> show variables like 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+
1 row in set (0.00 sec)

监控查询缓存的性能,使用显示状态查看缓存状态变量:

mysql> show status like 'qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 16768376 |
| Qcache_hits             | 0        |
| Qcache_inserts          | 0        |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 227      |
| Qcache_queries_in_cache | 0        |
| Qcache_total_blocks     | 1        |
+-------------------------+----------+
8 rows in set (0.00 sec)

  

mysql> select count(*) from animals;  
+----------+  
| count(*) |  
+----------+  
|        6 |   
+----------+  
1 row in set (0.00 sec)  
 
--Qcache_hits表示sql查询在缓存中命中的累计次数,是累加值。  
mysql> SHOW STATUS LIKE 'Qcache_hits';  
+---------------+-------+  
| Variable_name | Value |  
+---------------+-------+  
| Qcache_hits   | 0     |  --0次  
+---------------+-------+  
8 rows in set (0.00 sec)  
 
mysql>  select count(*) from animals;  
+----------+  
| count(*) |  
+----------+  
|        6 |   
+----------+  
1 row in set (0.00 sec)  
 
mysql>  SHOW STATUS LIKE 'Qcache%';  
+---------------+-------+  
| Variable_name | Value |  
+---------------+-------+  
| Qcache_hits   | 1     | --表示sql在缓存中直接获得结果,不须要再去解析  
+---------------+-------+  
8 rows in set (0.00 sec)  
 
mysql> select count(*) from animals;  
+----------+  
| count(*) |  
+----------+  
|        6 |   
+----------+  
1 row in set (0.00 sec)  
 
mysql> select count(*) from animals;  
+----------+  
| count(*) |  
+----------+  
|        6 |   
+----------+  
1 row in set (0.00 sec)  
 
mysql> SHOW STATUS LIKE 'Qcache_hits';  
+---------------+-------+  
| Variable_name | Value |  
+---------------+-------+  
| Qcache_hits   | 3     |    --上面的sql也是是从缓存中直接取到结果  
+---------------+-------+  
1 row in set (0.00 sec)  
 
mysql> insert into animals select 9,'testsds' ; --插入数据后,跟这个表全部相关的sql缓存就会被清空掉  
Query OK, 1 row affected (0.00 sec)  
Records: 1  Duplicates: 0  Warnings: 0  
 
mysql> select count(*) from animals;  
+----------+  
| count(*) |  
+----------+  
|        7 |   
+----------+  
1 row in set (0.00 sec)  
 
mysql> SHOW STATUS LIKE 'Qcache_hits';  
+---------------+-------+  
| Variable_name | Value |  
+---------------+-------+  
| Qcache_hits   | 3    |  --仍是等于3,说明上一条sql是没有直接从缓存中直接获得的  
+---------------+-------+  
1 row in set (0.00 sec)  
 
mysql> select count(*) from animals;  
+----------+  
| count(*) |  
+----------+  
|        7 |   
+----------+  
1 row in set (0.00 sec)  
 
mysql> SHOW STATUS LIKE 'Qcache_hits';   
+---------------+-------+  
| Variable_name | Value |  
+---------------+-------+  
| Qcache_hits   | 4     |   
+---------------+-------+  
1 row in set (0.00 sec) 
相关文章
相关标签/搜索