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值,同時增加寫線程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM