InnoDB儲存引擎之Master Thread,innodbmaster

來源:互聯網
上載者:User

InnoDB儲存引擎之Master Thread,innodbmaster
    InnoDB儲存引擎的主要工作都是在一個單獨的後台線程Master Thread中完成的。
    1.InnoDB 1.0.x版本之前的Master Thread

        Master Thread具有最高的線程優先順序別。其內部由多個迴圈組成:主迴圈(loop)、後台迴圈(backgroup loop)、重新整理迴圈(flush loop)、暫停迴圈(suspend loop)。Master Thread會根據資料庫啟動並執行狀態在上述4狀態下進行切換。Loop被稱為主迴圈,因為大多數的操作是在這個迴圈中,其中有兩大部分的操作:每秒的操作和每10秒的操作。虛擬碼如下:


        可以看到,loop迴圈通過thread sleep來實現,這意味著所謂的每秒一次或者每10秒一次的操作是不精確的。在負載很高的情況可能會有延遲,只能說大概在這個頻率下。當然InnoDB原始碼中還通過其他的方法來盡量保證這個頻率。
        每秒一次的操作:
            a.日誌緩衝重新整理到磁碟,即使這個事務還沒有提交(總是);
                即使某個是我還沒有提交,InnoDB儲存引擎仍然每秒會將重做日誌緩衝中的內容重新整理到重做記錄檔。這就可以解釋為什麼再大的事務提交的時間也很短。
            b.合并插入緩衝(可能);
                合并插入緩衝(Insert Buffer)並不是每秒都會發生。InnoDB儲存引擎會判斷當前一秒內發生的IO次數是否小於5次,如果小於5次,InnoDB認為當前的IO壓力很小,可以執行合并插入緩衝的操作。
            c.至多重新整理100個InnoDB的緩衝池中的髒頁到磁碟(可能);
                InnoDB儲存引擎通過判斷當前緩衝池中髒頁的比例(buf_get_modified_ratio_pct)是否超過了設定檔中innodb_max_dirty_pages_pct這個參數的值,如果超過了這個閥值,InnoDB儲存引擎認為需要做磁碟同步操作,將100個髒頁寫入磁碟。
            d.如果當前沒有使用者活動,則切換到background loop(可能);
        每10秒的操作:
            a.重新整理100個髒頁到磁碟(可能);
            b.合并至多5個插入緩衝(總是);
            c.將日誌緩衝重新整理到磁碟(總是);
            d.刪除無用的Undo頁(總是);
            e.重新整理100個或者10個髒頁到磁碟(總是);
        在以上的過程中,InnoDB儲存引擎會先判斷過去10秒內磁碟的IO操作是否小於200次,如果是,InnoDB儲存引擎認為當前有足夠的磁碟IO操作能力,因此將100個髒頁重新整理到磁碟。接著,InnoDB儲存引擎會合并插入緩衝,不同於每秒一次操作時可能發生的合并插入緩衝操作,這次的合并插入緩衝總是會進行。之後InnoDB儲存引擎會在進行一次將日誌重新整理到磁碟。這和每秒一次時發生的操作是一樣的。在接下來InnoDB儲存引擎會執行full purge操作,即刪除無用的Undo頁。在full purge過程中,InnoDB儲存引擎會判斷當前事務系統中已被刪除的行是否可以刪除,如果可以,則InnoDB會立即將其刪除。每次最多嘗試回收20個undo頁。然後,InnoDB儲存引擎會判定緩衝池中髒頁的比列如果有超過70%的髒頁,則重新整理100個髒頁到磁碟。如果比例小於70%則只需要重新整理10%的髒頁到磁碟。
        若當前沒有使用者活動(上巨款空閑時)或者資料庫關閉(shutdown),就會切換到這個迴圈。background loop會會執行以下操作:
            a.刪除無用的Undo頁(總是);
            b.合并20個插入緩衝(總是);
            c.跳回到主迴圈(總是);
            d.不斷重新整理100個頁直到符合條件(可能,跳轉到flush loop中完成);
        若flush loop中沒什麼事情可以做,InnoDB儲存引擎會切換到suspend loop,將Master Thread掛起,等待時間的發生。若使用者啟用(enable)了InnoDB儲存引擎,卻沒有使用任何InnoDB儲存引擎的表,那麼Master Thread總是處於掛起的狀態。
    2.InnoDB 1.2.x版本之前的Master Thread
        在InnoDB1.0.x版本之前,InnoDB儲存引擎對於IO其實是有限的,在緩衝池想磁碟排清時其實都做了一定的寫入程式碼(hard coding)。在SSD出現之後,這種規定在很大程度上限制了InnoDB儲存引擎對磁碟IO的效能,尤其是寫入效能。從前面的介紹來看,無論何時,InnoDB儲存引擎最大隻會重新整理100個頁到磁碟,合并20個插入緩衝。如果是在寫入密集的引用程式中,每秒可能會產生大於100個的髒頁,如果是產生大於20個插入緩衝的情況,Master Thread似乎總是會"忙不過來"。即使磁碟能在1秒內處理多餘100個頁的寫入和20個插入緩衝的合并,但是由於hard coding,Master Thread也只會選擇重新整理100個髒頁和合并20個插入緩衝。同時,當發生宕機需要恢複是,由於很多資料還沒有重新整理回磁碟,回到人恢複的時間肯能需要很久。針對這個問題InnoDB Plugin(從InnoDB1.0.x版本開始)提供了參數innodb_io_catacity,用來表示磁碟IO的輸送量,預設200。對於重新整理到磁碟頁的數量,會按照innodb_io_capacity的百分比來進行控制。規則如下:
            a.在合并插入緩衝時,合并插入緩衝的數量為innodb_io_capacity值的50%;
            b.在從緩衝區重新整理髒頁時,重新整理的髒頁的數量為innodb_io_capacity;
        若使用者使用了SSD類的磁碟,或者將幾塊磁碟做了RAID。當存放裝置擁有更高的IO速度是,可以將innodb_io_capacity的值調大寫,知道符合磁碟IO的輸送量。InnoDB1.0.x版本的另一個參數innodb_adaptive_flushing(自適應地重新整理),該值影響每秒重新整理髒頁的數量。原來的重新整理規則是:髒頁在緩衝所佔比例小於innodb_max_dirty_pages_pct時,不重新整理髒頁,大於innodb_max_dirty_pages_pct時,重新整理100個髒頁。隨著innodb_adaptive_flushing參數的引入,InnoDB儲存引擎會通過一個buf_flush_get_desired_flush_rate的函數來判斷需要重新整理髒頁最合適的數量。大致的做法是通過判斷產生重做日誌的速度來決定最合適的重新整理髒頁數量。因此,當髒頁的比列小於innodb_max_dirty_pages_pct時,也會重新整理一定量的髒頁。

        還有一個改變是:之前每次進行full purge操作時,最多回收20個Undo頁。從InnoDB1.0.x版本開始引入參數innodb_purge_batch_size,該參數可以控制每次full purge回收的Undo頁的數量,預設20。可以動態對其進行修改。通過命令show engine innodb status可以查看檔期Master Thread的狀態資訊。如:


        有圖可知,主迴圈進行了1154432次,每秒掛起(sleep)的操作進行了1154432次,10秒一次的活動進行了106465次,background loop進行了90829次,flush loop進行了90829次。
    3.InnoDB 1.2.x版本的Master Thread
        InnoDB 1.2.x版本中,Master Thread的虛擬碼如下:
           
        其中srv_master_do_idle_tasks()就是之前版本中每10秒的操作,srv_master_do_active_tasks()處理的是之前每秒中的操作。對於重新整理髒頁的操作,從Master Thread線程分離到一個單獨的Page Cleaner Thread,從而減輕了Master Thread的工作,同時進一步提高了系統的並發性。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

Tags Index: