zoukankan      html  css  js  c++  java
  • innodb master thread 工作原理

     

    参考 innodb参数汇总  InnoDB的Master Thread工作原理

    innodb_max_dirty_pages_pct 默认值

    show variables like 'innodb_max_dirty_pages_pct';

        由90%变为了75%。加快了脏页刷新频率减少恢复时间,也可保证磁盘IO负载。


    innodb_adaptive_flushing(自 适应刷新)
       影响每秒刷新脏页的数目。规则由原来的“大于innodb_max_dirty_pages_pct时刷新100个脏页到磁盘”变为 “通过buf_flush_get_desired_flush_reate函数判断重做日志产生速度确定需要刷新脏页的最合适数目”;即使脏页比例小于 innodb_max_dirty_pages_pct时也会刷新一定量的脏页。
     
    innodb_io_capacity

    查看:show variables like 'innodb_io_capacity';

    无论何时,InnoDB存储引擎最多都只会刷新100个脏页到磁盘,合并20个插入缓冲。如果是在密集写的应用程序中,每秒中可能会产生大于100个的脏页,或是产生大于20个插入缓冲,此时master thread似乎会“忙不过来”,或者说它总是做得很慢。即使磁盘能在1秒内处理多于100个页的写入和20个插入缓冲的合并,由于hard coding,master thread也只会选择刷新100个脏页和合并20个插入缓冲。同时,当发生宕机需要恢复时,由于很多数据还没有刷新回磁盘,所以可能会导致恢复需要很快的时间,尤其是对于insert buffer。

    这个问题最初是由Google的工程师Mark Callaghan提出的,之后InnoDB对其进行了修正并发布了补丁。InnoDB存储引擎的开发团队参考了Google的patch,提供了类似的方法来修正该问题。因此InnoDB Plugin开始提供了一个参数,用来表示磁盘IO的吞吐量,参数为innodb_io_capacity,默认值为200。对于刷新到磁盘的数量,会按照innodb_io_capacity的百分比来刷新相对数量的页。规则如下:

    在合并插入缓冲时,合并插入缓冲的数量为innodb_io_capacity数值的5%。

    在从缓冲区刷新脏页时,刷新脏页的数量为innodb_io_capacity。

    innodb_fast_shutdown
     
    innodb_fast_shutdown影响着innodb表的行为,该参数可设置为0,1,2
     0 表示当MySQL关闭时,InnoDB需要完成所有的full purge和merge insert buffer操作。耗时比较长。
    1 是默认值。表示不需要完成full purge和merge insert buffer操作,但是在缓冲池中的一些数据脏页会刷新到磁盘。
    2 表示不完成full purge和merge insert buffer操作,也不将缓冲池中的数据脏页写回到磁盘,而是将日志写入到日志文   件。MySQL下次启动时,会执行恢复操作。
     
    innodb_force_recovery
        影 响InnoDB的恢复状况。默认为0,表示需恢复时执行所有的恢复操作。若不能有效恢复,则MySQL有可能宕机,错误信息会被写入错误日志文件。还有 1~6等值
     
     

    master thread可以分为主循环(loop),background循环,flush循环,suspend循环。可以这么理解,先运行主循环,如果当前数据库空闲,或者调用stop关闭命令时,进入background循环,在background循环最后,如果当前数据库不再空闲,就重新进入主循环,否则进入flush循环。在flush循环最后,如果数据库还是空闲就进入suspend循环,master thread挂起。

      主循环分成两部分,一部分是每一秒钟要做的事情,另一部分是每10秒钟要做的事情。伪代码如下:

      loop:
        for(int i=0;i<10;i++){
         thread_sleep(1);//sleep 1 second
         doing something{
          //每一秒钟要做的
          do log buffer flush to disk;
          if(last_one_second_ios < 5%*innodb_io_capacity){
          do merge at most 5% innodb_io_capacity insert buffer;
         }
         if(buffer_pool_modified_page_ratio_pct > innodb_max_dirty_page_pct){
          do buffer pool flush 100% innodb_io_capacity dirty pages;
         }else if(enable adaptive flush){
          do buffer pool flush desired amount dirty pages;
         }
         if(not user activity){
          goto background loop;
         }
        } 
       }
       doging something;{
        //每10秒要做的
        if(last_ten_seconds_ios < innodb_io_capacity){
          do merge 100% innodb_io_capacity dirty pages;
        }
        do log buffer flush to disk;
        do merge at most 5% innodb_io_capacity insert buffer;
        do full purge,at most 20 undo pages;
        if(buffer_pool_modified_page_ratio_pct < 70%){
          do buffer pool flush 100% innodb_io_capacity dirty pages;
        }else{
          do buffer pool flush 10% innodb_io_capacity dirty pages;
        }
        do fuzzy checkpoint;
       }

      background loop循环伪代码如下:

      background loop:
        do full purge,at most 20 undo pages;
        do merge 100% innodb_io_capacity insert buffer;
        if(not idle){
          goto loop;
        }else{
          goto flush loop;
        }

      flush loop循环伪代码如下:

      flush loop:
        do buffer pool flush 100% innodb_io_capacity dirty pages;
        if(buffer_pool_modified_page_ratio_pct > innodb_max_dirty_page_pct){
          goto flush loop;
        }
        goto suspend loop;

      suspendloop循环伪代码如下:

      suspend loop:
        suspend thread();
        waiting event;
        goto loop;

      通过整理不难发现,整个master thread主要操作的对象只有,log buffer,insert buffer,dirty pages,undo pages,checkpoint。可以根据这些操作对象来分类主要有如下:

      log buffer:

        只在主循环中操作log buffer。而且,不管是在每一秒,还是每10秒,不需要任何前提,都会flush log buffer.这个最好理解。

      insert buffer:

        每一秒操作:如果一秒内磁盘IO < 5% innodb_io_capacity,就至多合并5% innodb_io_capacity的insert buffer.否则就不操作。

        每10秒操作:不需要任何前提,至多合并5% innodb_io_capacity的insert buffer。

        background loop:至多合并100% innodb_io_capacity的insert buffer。

      dirty pages:

        每一秒操作:如果缓冲池脏页比例 > innodb_max_dirty_pages_pct,就刷新100%innodb_io_capacity的脏页到磁盘。如果不满足条件,但是满足adaptive flush条件,仍会刷新一定的脏页到磁盘

        每10秒操作:如果最近10秒内,磁盘IO < innodb_io_capacity,就刷新100%innodb_io_capacity的脏页到磁盘。之后,如果缓冲池脏页比例 > 70% ,再次刷新100%innodb_io_capacity的脏页到磁盘,否则刷新10%innodb_io_capacity。

        flush loop:只要缓冲池脏页比例 > innodb_max_dirty_pages_pct,就刷新100%innodb_io_capacity的脏页到磁盘,直到脏页比例小于innodb_max_dirty_pages_pct设置。

      undo pages:

        每10秒操作 :不需要任何前提,至多删除20个undo 页.

        background loop : 不需要任何前提,至多删除20个undo 页.

      checkpoint :

        每10秒操作 :不需要任何前提,设置一个模糊检查点.

  • 相关阅读:
    myEclipse Debug
    C# DataTable的詳細使用方法
    算法 《秦九韶算法java实践》
    【闲聊产品】之五:谁来背黑锅?
    ubuntu install mysql server method
    H264解码的一个測试程序
    Struts2自己定义拦截器实例—登陆权限验证
    【剑指offer】二叉树的镜像
    ubuntu12.04下搭建ftpserver
    C++Vector使用方法
  • 原文地址:https://www.cnblogs.com/taek/p/4730331.html
Copyright © 2011-2022 走看看