1. 程式人生 > >MySQL後臺線程整理總結

MySQL後臺線程整理總結

thread類 刪除 有關 mod 交互 per 模式 span pan

本文整理自《MySQL技術內幕 InnoDB存儲引擎》

MySQL通過後臺各種線程、內存池、文件交互來實現對外服務的,不同線程實現不同的資源操作,各個線程相互協助,共同來完成數據庫的服務。
以下簡單總結MySQL的一些後臺線程以及主要作用,以及innodb引擎的變化升級情況。

整體上看,MySQL的後臺線程概括如下,分為master thread,IO thread,purge thread,page cleaner thread

技術分享圖片

這其中,Master Thread是MySQL的最核心的線程,其中實現了多種功能,同時也在不斷地改進與優化。
InnoDB 1.2.X之前版本的Master Thread主要工作內容,

如下是偽代碼來描述 Master Thread

MasterThread
{

    //每1秒一次操作涉及的行為
    PerSecondOperation()
    {
        1,刷新redo日誌緩沖到磁盤,不管是否提交(總是)
      屬於master thread中的checkpoint實現
2,合並插入緩沖(可能),根據一秒之內發生的IO次數,如果小於5,則執行合並插入緩沖的操作
3,最多刷新100個Innodb緩沖池中的臟頁到磁盤(可能), if(buf_get_modified_ratio_pct>buf_max_dirty_pages_pct>buf_get_modified_ratio_pct)   執行刷新100個臟頁到磁盤
4,如果當前沒有用戶活動,切換到background模式 } //每10秒一次操作涉及的行為 TenSecondOperation() { 1,刷新100個Innodb緩沖池中的臟頁到磁盤(可能), 判斷過去10秒之內IO操作是否小於200次,如果是,刷新100個臟頁到磁盤------>硬編碼
2,合並最多5個插入緩沖(總是),無條件,總是執行合並最多5個插入緩沖
3,日誌緩存刷新到磁盤(總是)
4,刪除無用的undo頁(總是),每次最多嘗試回收20個頁---->硬編碼
5,刷新100或者10個臟頁到磁盤(總是):---->硬編碼 臟頁比例>70%==>刷新100個臟頁到磁盤, 臟頁比例<70%==>刷新10個臟頁到磁盤 } //BackgroundOperation線程 BackgroundOperation() { 1,刪除無用的Undo頁(總是)
2,合並20個插入緩沖(總是)
3,跳回到主循環(總是)
4,不斷刷線100個直到page到磁盤,直到滿足(臟頁小於參數buf_max_dirty_pages_pct)。 } }

不難發現,InnoDB 1.2.X之前的版本寫死了很多參數,
InnoDB 1.2.X之後版本的Master Thread根據實際情況,靈活地增加了一些配置參數,尤其是與IO有關的innodb_io_capacity參數。
innodb_io_capacity表示物理存儲的IO能力,在後臺線程與物理存儲IO交互的時候,由於不同的存儲設備有不同的IO處理能力,
innodb_io_capacity就表示物理存儲的IO處理能力的參,默認值是200
通過根據實際存儲情況對innodb_io_capacity的配置,可以最大化地提高MySQL服務器的處理性能。


MasterThread
{

    1,增加參數innodb_io_capacity,合並插入緩沖=innodb_io_capacity*5%;刷新臟頁數量=innodb_io_capacity
    2,buf_max_dirty_pages_pct默認值修改為75%
    3,innodb_purge_batch_size,回收undo頁的配置,默認值20


    //每1秒一次操作涉及的行為
    PerSecondOperation()
    {
        1,刷新redo日誌緩沖到磁盤,不管是否提交(總是)
           屬於master thread類型的checkpoint

        2,合並插入緩沖(可能),根據一秒之內發生的IO次數:
           if(過去1秒鐘的ios<5%innodb_io_capacity)
           {    
               執行合並5%innodb_io_capacity個page的插入緩沖的操作
           }

        3,刷新緩沖池中的臟頁到磁盤(可能):
           if(buf_get_modified_ratio_pct>buf_max_dirty_pages_pct)
                刷新臟頁個數:100%*innodb_io_capacity
           if(buf_get_modified_ratio_pct<buf_max_dirty_pages_pct)
                刷新臟頁個數:10%*innodb_io_capacity

        4,如果當前沒有用戶活動,切換到background模式

    }
    //每10秒一次操作涉及的行為
    TenSecondOperation()
    {
    
        1,刷新緩沖池中的臟頁到磁盤(可能):
           if(buf_get_modified_ratio_pct>buf_max_dirty_pages_pct)
                刷新臟頁個數:100%*innodb_io_capacity
           if(buf_get_modified_ratio_pct<buf_max_dirty_pages_pct)
                刷新臟頁個數:10%*innodb_io_capacity

        
        2,合並插入緩沖(可能),根據過去一秒之內發生的IO次數:
            if(ios<5%innodb_io_capacity)
            {    
                執行合並5%innodb_io_capacity個page的插入緩沖的操作
            }

        3,日誌緩存刷新到磁盤(總是)
        
        4,刪除無用的undo頁(總是)
           根據參數:innodb_purge_batch_size
    }

    BackgroundOperation()
    {
        1,刪除無用的Undo頁(總是)

2,合並innodb_io_capacity個插入緩沖(總是)
3,跳回到主循環(總是)
4,不斷刷線innodb_io_capacity個page到磁盤,直到滿足(臟頁小於參數buf_max_dirty_pages_pct)。 } }

獨立的page cleaer thread

PageCleanerThread()
{
    
    1,刷新緩沖池中的臟頁到磁盤(可能):
        if(buf_get_modified_ratio_pct>buf_max_dirty_pages_pct)
            刷新臟頁個數:100%*innodb_io_capacity
        if(buf_get_modified_ratio_pct<buf_max_dirty_pages_pct)
            刷新臟頁個數:10%*innodb_io_capacity
}

MySQL後臺線程整理總結