innoDB 線程分析之Master Thread

一、Master Thead簡單介紹

innoDB存儲引擎的主要工作都是由Master Thread 完成的。master thread的線程優先級別最高。其內部幾個循環(loop)組成:主循環(loop),後臺循環(background loop),刷新循環(flush loop),暫停循環(suspend loop).master thread會根據數據運行的狀態在loop,background loop,flush loop和suspend loop中進行切換.
 loop稱爲主循環,因爲大多數的操作都在這個循環中,其中有兩大部分操作:每秒鐘的操作和每10秒的操作。

二、兩種操作

1、每秒一次的操作包括:
    1)日誌緩衝刷新到磁盤,即使這個事務還沒有提交(總是)
    2)合併插入緩衝(可能)
    3)至多刷新100個innodb的緩衝池中的髒頁到磁盤(可能)
    4)如果當前沒有用戶活動,切換到background loop(可能)
    即使某個事務還沒有提交,innodb存儲引擎仍然會每秒將重做日誌緩衝中的內容刷新到重做日誌文件.這一點是必須知道的,這可以很好地解釋爲什麼再大的事務commit的時間也是很快的
    合併插入緩衝(insert buffer)並不是每秒都發生.innodb存儲引擎會判斷當前一秒內發生的io次數是否小於5次,如果小於5次,innodb認爲當前的io壓力很小,可以執行合併插入緩衝的操作
    同樣,刷新100個髒頁也不是每秒都在發生.innodb存儲引擎通過判斷當前緩衝池中的髒頁比例(buf_get_modified_ratio_pct)是否超過了配置文件中innodb_max_dirty_pages_pct這個參數(默認爲90,代表90%),如果超過了這個闕值,innodb存儲引擎認爲需要做磁盤同步操作,將100個髒頁寫入磁盤.

2、每10秒的操作

    1)刷新100個髒頁到磁盤(可能)
    2)合併至多5個插入緩衝(總是)
    3)將日誌緩衝刷新到磁盤(總是)
    4)刪除無用的undo頁(總是)
    5)刷新100個或者10個髒頁到磁盤(總是)
    6)產生一個檢查點(總是)

在以上過程中,innodb存儲引擎會先判斷過去10秒之內的磁盤的io操作是否小於200次.如果是,innodb存儲引擎認爲當前有足夠的磁盤io能力,因此將100個髒頁刷新到磁盤.接着,innodb存儲引擎會合並插入緩衝.不同於1秒操作時可能發生的合併插入緩衝操作,這次的合併插入緩衝操作總會在這個階段進行.之後,innodb存儲引擎會再執行一次將日誌緩衝刷新到磁盤的操作,這與每秒發生的操作是一樣的.

    接着innodb存儲引擎會執行一步full purge操作,即刪除無用的undo頁.對錶執行update,delete這類操作時,原生的行被標記爲刪除,但是因爲一致性讀的關係,需要保留這些行版本的信息.但是在full purge過程中,innodb存儲引擎會判斷當前事務系統中已被刪除的行是否可以刪除,比如有時候可能還有查詢操作需要讀取之前版本的undo信息,如果可以,innodb會立即將其刪除.從源代碼中可以發現,innodb存儲引擎在操作full purge時,每次最多刪除20個undo頁.

    然後innodb存儲引擎會判斷緩衝池中髒頁的比例,如果有超過70%的髒頁,則刷新100個髒頁到磁盤;如果髒頁得比例小於70%,則只需要刷新10的髒頁到磁盤

    最後,innodb存儲引擎會產生一個檢查點(checkpoint),innodb存儲引擎的檢查點也被稱爲模糊檢查點(fuzzy checkpoint).innodb存儲引擎在checkpoint時並不會把所有緩衝池中的髒頁都寫到磁盤,因爲這樣可能會對性能產生影響,而只是將最老日誌序列號的頁寫入磁盤。

 接着來看background loop,若當前沒有用戶活動(數據庫空閒時)或者數據庫關閉時,就會切換到這個循環.這個循環會執行如下操作:
    刪除無用的undo頁(總是).
    合併20個插入緩衝(總是).
    跳回到主循環(總是).
    不斷刷新100個頁,直到符合條件(可能,跳轉到flush loop中完成)
    如果flush loop中也沒有什麼事情可以做了,innodb存儲引擎會切換到supend_loop,將master thread掛起,等待事件的發生.若啓用了innodb存儲引擎,卻沒有使用任何存儲引擎的表,那麼master thread總是處於掛起狀態.

三、僞代碼

 接着來看background loop,若當前沒有用戶活動(數據庫空閒時)或者數據庫關閉時,就會切換到這個循環.這個循環會執行如下操作:
    刪除無用的undo頁(總是).
    合併20個插入緩衝(總是).
    跳回到主循環(總是).
    不斷刷新100個頁,直到符合條件(可能,跳轉到flush loop中完成)
    如果flush loop中也沒有什麼事情可以做了,innodb存儲引擎會切換到supend_loop,將master thread掛起,等待事件的發生.若啓用了innodb存儲引擎,卻沒有使用任何存儲引擎的表,那麼master thread總是處於掛起狀態.

  1. void master_thread(){  
  2.     goto loop;  
  3.     loop:  
  4.     for(int i=0;i<10;i++){  
  5.         thread_sleep(1);  
  6.         do log buffer flush to disk  
  7.         if(last_one_second_ios < 5)  
  8.         do merge at most 5 insert buffer  
  9.         if(buf_get_modifed_ratio_pct > innodb_max_dirty_pages_pct)  
  10.         do buffer pool flush 100 dirty page  
  11.         if(no user activity)  
  12.         goto background loop      
  13.     }  
  14.     if(last_ten_second_ios<200)  
  15.         do buffer pool flush 100 dirty page  
  16.     do merge at most 5 insert buffer  
  17.     do log buffer flush to disk  
  18.     do full purge  
  19.     if(buf_get_modified_ratio_pct > 70%)  
  20.         do buffer pool flush 100 dirty page      
  21.     else  
  22.         do buffer pool flush 10 dirty page  
  23.     do fuzzy checkpoint  
  24.     goto loop  
  25.     background loop:  
  26.     do full purge  
  27.     do merge 20 insert buffer  
  28.     if not idle:  
  29.     goto loop:  
  30.     else:  
  31.         goto flush loop  
  32.     flush loop:  
  33.     do buffer pool flush 100 dirty page              
  34.     if(buf_get_modified_ratio_pct > innodb_max_dirty_pages_pct)  
  35.         goto flush loop  
  36.     goto suspend loop  
  37.         suspend loop:  
  38.     suspend_thread();  
  39.         waiting event  
  40.     goto loop;      
  41.  }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章