1.IO THREAD: 負責IO的相關線程IO THREADhtml
1. 參數innodb_write_io_threads 寫線程 默認四個,負責數據塊的寫入 2. 參數innodb_read_io_threads 讀線程 默認四個,負責數據塊的讀取mysql 上面兩個參數高併發下,能夠設置爲8.sql 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=1,2,3;高併發 此時delete from tb1 where pk=1; 1. 將pk=1的記錄標記爲刪除(delete-mark,infobits),數據庫中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操做時,每次最多嘗試回收20個undo 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. |
在MySQL5.6中,開啓了一個獨立的page cleaner線程來進刷lru list 和flush list。默認每秒運次1次.MySQL5.7 可設置多個page cleaner線程提升髒頁刷新效率 ; 1、5.6版本之前,髒頁的清理工做交由master線程的; 2、Page cleaner thread是5.6.2引入的一個新線程(單線程),從master線程中卸下buffer pool刷髒頁的工做獨立出來的線程(默認是啓一個線程); 3、5.7開始支持多線程刷髒頁; show global status like '%Innodb_buffer_pool_wait_free%'; 若是值很大,則須要增長innodb_page_cleaners值,同時增長寫線程。 |