1. 程式人生 > >innodb之執行緒及IO相關引數介紹

innodb之執行緒及IO相關引數介紹

引用連結:http://www.cnblogs.com/henglxm/p/4284504.html

 

1.IO THREAD: 負責IO的相關執行緒IO THREAD

1. 引數innodb_write_io_threads  寫執行緒 預設四個,負責資料塊的寫入

2. 引數innodb_read_io_threads 讀執行緒  預設四個,負責資料塊的讀取

上面兩個引數高併發下,可以設定為8.

show variables like '%write_io%'

show variables like '%read_io%'

也可通過mysql> show engine innodb status\G;檢視IO thread.

 

2.Purge thread

作用真正的刪除記錄和刪除undo log

 1.清理刪除後的資料頁的空間(因為之前的刪除只是打上刪除標籤,並沒有正真刪除),

 2.清理undo

舉例:tb1中有記錄pk=123;

此時delete from tb1 where pk=1;

1. pk=1的記錄標記為刪除(delete-markinfobits),資料庫中pk=1

的記錄此時還是存在的,空間並沒有被釋放,該操作為同步操作(SQL執行完,也就標記完成了)

2. purge ,該部分為後臺執行緒(purge執行緒)非同步操作,會真正的刪除該記錄,且空間被釋放。

標記為已刪除的原因:

1. 該事物可能需要回滾,先作保留。

2. 當事物1去刪除pk=1且沒有提交時, 事物2應該要能看到pk=1的記錄(事物的隔離性)

過濾條件是聚簇索引:

1. delete – 將該記錄標記為 delete-mark 

2. update – 將該記錄 先物理delete (聚簇索引裡主鍵相同的行最多隻能有

1),然後 insert (或者可以原地更新[in place update])(即使刪除了,也可以通過undo進行還原)

過濾條件是二級索引:

1. delete – 將該記錄標記為 delete-mark 

2. update – 將該記錄標記為 delete-mark (索引列是columns + pk,即使是唯一索引更新也是和原來的不一樣),然後 insert 

為什麼沒有insert

1. insert操作是不需要非同步去purge,因為insert的記錄之前是不存在的;

2.不存在記錄(未提交)是沒有別的事物能引用到的,所以insert以後,對應的undo可以直接刪除,而不需要等待非同步.

purge 總結:

1. delete-mark的記錄最後會被purge執行緒回收,Purge會檢測記錄上是否有其他事物在引用undo,如果沒有就可以刪除。

2. innodb_purge_threads (5.6以後),可以設定的大一些,回收的速度會快一些。

innodb_purge_threads = 4

 

3.Insert-buffer thread

 負責insert buffer與輔助索引的合併操作。

 

4.redo-log thread

 負責重做日誌緩衝的磁碟寫入

 

5.Master thread(主執行緒)

master thread的執行緒優先級別最高。
後臺程序Master thread 裡面有兩種迴圈,再迴圈內可以呼叫其他執行緒進行相關的操作。

其內部幾個迴圈(loop)組成:主迴圈(loop),後臺迴圈(background loop),重新整理迴圈(flush loop),暫停迴圈(suspend loop)。主迴圈有1s迴圈和10s迴圈. 1s迴圈即迴圈執行一次就sleep 1s後又執行一次又sleep 1 s.

每秒一次的操作包括 :

1.日誌緩衝重新整理到磁碟, 即使事務沒有提交(commit).

注意即使事務沒有提交操作, innodb 重做日誌快取仍然會重新整理到重做日誌檔案, 所以就算很大的事務操作的commit沒有想象中那麼慢.  

2.合併插入緩衝(可能),合併插入緩衝不一定每秒都執行, innodb引擎會判斷當前1秒內發生的IO次數是否小於5, 如果小於5.則合併插入緩衝.

3. 最多重新整理100 innodb緩衝池中的髒頁到磁碟(可能),innodb儲存引擎通過判斷當前緩衝池中髒頁的比例()是否超過配置檔案中innodb_max_dirty_pages_pct這個引數的值.如果超過了這個閥值 ,innodb儲存引擎則認為需要做磁碟同步操作,重新整理100個髒頁到磁碟.

4. 如果當前使用者沒有活動, 切換到 background thread (可能)

10秒執行的操作 :

1 .重新整理100個髒頁到磁碟 (總是)

2. 合併最多5個插入緩衝(總是)

3. 將日誌緩衝重新整理到磁碟(總是)

4. 刪除無用的Undo(總是)

5. 重新整理100個或者10個髒頁到磁碟(總是)

10秒的迴圈操作中. innodb儲存引擎首先判斷過去10秒內的磁碟IO操作是否小於200, 如果小於,則將100個髒頁重新整理到磁碟.  然後合併 (最多5)插入緩衝, 然後將重做日誌緩衝重新整理到日誌檔案.然後,innodb儲存引擎會執行一次full purge. 既刪除無用的undo. 對錶(磁碟)進行update, delete這類操作時,原先被標記為刪除,但是因為一致性讀(consistent read)的關係, 需要保留這些行版本的資訊. 但是在full purge 過程中, innodb儲存引擎會判斷當前事務中已被刪除的行是否可以在表(磁碟)中刪除,如果可以,則立刻刪除.  innodb在執行full purge操作時,每次最多嘗試回收20undo page. 最後innodb儲存引擎會判斷緩衝池中髒頁的比例,  如果超過70%, 則重新整理100個髒頁到磁碟, 如果髒頁比例小於70%,則是重新整理10%的髒頁到磁碟

background loop :若當前沒有使用者活動或者資料庫關閉(shutdown),就會切換到這個迴圈. background loop 會執行以下操作.

1 .刪除無用的 undo (總是)

2. 合併20個插入緩衝頁(總是)

3. 跳回到主迴圈(總是)

4. 不斷重新整理到100個髒頁直到符合條件(可能, 跳轉到flush loop 中完成)

flush loop 中也沒有什麼事情可以做了, innodb儲存引擎會切換到suspend_loop. master_thread掛起, 等待事件發生.若用在mysql中啟用了innodb儲存引擎,但沒有建立innodb, master thread總是處於掛起狀態。

檢視後臺執行緒:

mysql> Show engine innodb status\G;

srv_master_thread loops: 56 1_second, 56 sleeps, 5 10_second, 6 background, 6 flush

srv_master_thread log flush and writes: 56

其中 srv_master_thread loops: 56 表示主迴圈進行了,56. 56 sleeps 表示掛起56, 5 10_second 表示10秒的迴圈執行了5. background loop執行6, flush loop執行6 如果 srv_master_thread loops sleeps 存在較大差距,則表明當前伺服器可能很比較繁忙 , 因為innodb在其內部進行了優化, 在壓力大的情況下,1秒迴圈並不是每次都sleep 。

 

6. IO有關引數

 innodb_io_capacity(落髒個數) . innodb_write_io_threads(寫IO) .innodb_read_io_threads(讀IO)     innodb_page_cleaners(刷髒頻次)


  1. 落盤髒頁個數引數(
innodb_io_capacity)

引數 :innodb_io_capacity :資料庫落盤髒頁個數 ,配置壓力和磁碟的效能相關,如果過大,IO能力不足,則出現卡頓。

innodb_io_capacity預設是200,單位是頁,該引數的設定大小取決於硬碟的IOPS,即每秒的輸入輸出量(或讀寫次數)。

可以動態調整引數:set global innodb_io_capacity=2000;

檢視 innodb_io_capacity值: show variables like '%innodb_io_cap%';

配置建議如下: 

innodb_io_capacity           磁碟配置

200                    單盤SAS/SATA

2000                    SAS*12  RAID10

5000                    SSD

20000                   FUSION-IO

建議:儘量不要超過20000.

       

   2. IO讀寫引數(innodb_write_io_threads,innodb_read_io_threads

引數innodb_write_io_threads和innodb_read_io_threads 分別負責資料塊的寫入和讀取,預設是4,高併發可設定為8.

  

              3. 重新整理lru list flush list的引數(innodb_page_cleaners
 MySQL5.6中,開啟了一個獨立的page cleaner執行緒來進刷lru list flush list。預設每秒運次1.MySQL5.7 可設定多個page cleaner執行緒提高髒頁重新整理效率 ;

15.6版本以前,髒頁的清理工作交由master執行緒的;

2Page cleaner thread5.6.2引入的一個新執行緒(單執行緒),從master執行緒中卸下buffer pool刷髒頁的工作獨立出來的執行緒(預設是啟一個執行緒)

35.7開始支援多執行緒刷髒頁;

show global status like '%Innodb_buffer_pool_wait_free%';

如果值很大,則需要增加innodb_page_cleaners值,同時增加寫執行緒。