• 浅谈mysql innodb缓存策略


    浅谈mysql innodb缓存策略:

     

     The InnoDB Buffer Pool

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

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

       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将成为替换或驱逐的候选者。

         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) 

      

  • 相关阅读:
    node.js
    Ajax常见面试题
    CF932E Team Work
    斯特林数
    UOJ #62. 【UR #5】怎样跑得更快
    洛谷 P4593 【[TJOI2018]教科书般的亵渎】
    洛谷 P4321 【随机漫游】
    洛谷 P4707 【重返现世】
    洛谷 P3175 [HAOI2015]按位或
    CF Gym101933K King's Colors
  • 原文地址:https://www.cnblogs.com/onlysun/p/4513029.html
Copyright © 2020-2023  润新知