MySQL:Innodb page clean 執行緒 (一) 基礎
本文為學習筆記,有誤請指出。本文第一分部為基礎部分第二部分為解析部分涉及部分原始碼淺析。
本文使用原始碼版本:Percona 5.7.14
本文約定
-協調工作執行緒:因為page clean執行緒的協調執行緒也會完成部分重新整理工作,所以叫做協調工作執行緒。
一、page clean執行緒概念
Innodb中page clean執行緒將髒資料寫入到磁碟,髒資料寫盤後相應的redo就可以覆蓋,然後達到redo迴圈使用的目的。在5.7中引數可以開啟多個page clean執行緒服務於多個innodb buffer例項如下:
The innodb_page_cleaners default value was changed from 1 to 4 in MySQL 5.7. If the number of page cleaner threads exceeds the numberof buffer pool instances, innodb_page_cleaners is automatically set to the same value asinnodb_buffer_pool_instances.
實際上在內部實現中如果page clean執行緒為4個那麼包含一個協調工作執行緒和三個工作執行緒,這個協調工作執行緒也要完成一部分工作。在MySQL中我們可以透過語句檢視到這些工作執行緒:
| 17 | 57982 | innodb/page_cleaner_thread | NULL | BACKGROUND | NULL | NULL || 18 | 57983 | innodb/page_cleaner_thread | NULL | BACKGROUND | NULL | NULL || 19 | 57984 | innodb/page_cleaner_thread | NULL | BACKGROUND | NULL | NULL || 20 | 57985 | innodb/page_cleaner_thread | NULL | BACKGROUND | NULL | NULL |
實際上在我淺析分析中發現,所有的工作執行緒都是不斷輪序每一個和buffer instance對應的槽(slot),直到所有的buffer instance都已經進行了刷髒工作為止,並沒有固定那個工作執行緒服務於那個buffer instance例項。
二、重新整理方式
總的來說page clean執行緒重新整理的方式分為三種如下:
1、 活躍重新整理
一般來講我們線上的資料庫一般都處於活躍狀態,只要有DML/DDL等用到語句都會處於活躍狀態,但是SELECT不包含在活躍狀態下。這種狀態下重新整理會開啟一個協調工作執行緒和多個工作執行緒同時工作,這種狀態其重新整理的塊數演算法為(page_cleaner_flush_pages_recommendation函式):
-
(根據引數計算出來的頁數量 +以往每秒重新整理頁的數量+根據target lsn 計算出來的一個需要重新整理的塊數)/3
實際上這裡需要關注的就是(根據引數計算出來的頁數量),演算法大概如下(af_get_pct_for_dirty函式):
如果innodb_max_dirty_pages_pct_lwm沒有開: 如果髒資料比率大於等於innodb_max_dirty_pages_pct的設定: 則返回100% 如果innodb_max_dirty_pages_pct_lwm開啟: 如果髒資料比率大於等於innodb_max_dirty_pages_pct_lwm: 則返回(髒資料比率*100)/(innodb_max_dirty_pages_pct+1)這樣一個百分比
我們計上面的百分比為A,除了百分比A還和innodb_adaptive_flushing、innodb_adaptive_flushing_lwm計算出來的百分比有關,我們記做B(af_get_pct_for_lsn函式計算),但是由於引數innodb_cleaner_lsn_age_factor預設設定為high_checkpoint,所以這個百分比比較小,具體演算法見後文,其最後取值
-
根據引數計算出來的頁數量 = MAX(A,B)*innodb_io_capacity
2、空閒重新整理
一般情況下除了活躍重新整理就是空閒重新整理,空閒的情況下因為伺服器IO應該比較空閒,所以Innodb使用協調工作執行緒本身進行重新整理,重新整理的塊數計算比較簡單就是innodb_io_capacity設定的值。
3、 同步重新整理
同步重新整理則是堵塞重新整理,所有需要寫髒資料庫的使用者執行緒都會堵塞,這是很嚴重的情況。在checkpoint的時候
會檢查或者DML語句執行過程中都會檢查redo是否處於一個安全的位置,這是呼叫log_free_check函式進行,如果認為髒的塊數太多,redo已經處於不安全的位置(log_checkpoint_margin),那麼同步重新整理會被喚醒。
關於這部分在原始碼部分還會提到。
三、關於一個警告
警告如下:
page_cleaner: 1000ms intended loop took **ms. The settings might not be optimal.((flushed="**" , during the time.)
實際上這個警告來自於兩次重新整理時間的檢測:
-
本次重新整理時間 - 上次重新整理時間 > 1秒(睡眠時間)+3秒 則報警告
這個警告一般是IO能力不足,或者引數不夠最佳化的結果,有了上面的基礎我們知道這裡應該做如下操作:
-
innodb_io_capacity 應該降低
-
innodb_max_dirty_pages_pct 應該降低
-
innodb_max_dirty_pages_pct_lwm 如果設定了應該考慮降低
-
-
innodb_io_capacity_max 考慮降低涉及到上面說的百分比B的計算(af_get_pct_for_lsn函式)
降低的目的在於減少每次重新整理的量,讓每次重新整理塊數更加平均。從而避免page clean 執行緒爆發性的重新整理髒資料庫,從而堵塞IO通道。如果慢慢調整後還是不行則考慮IO確實扛不住了。
關於這部分在原始碼部分還會提到。
後文將會對得到這些結論的原始碼進行解析。
作者微信:
微信.jpg
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2157988/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL:Innodb page clean 執行緒 (二) 解析MySql執行緒
- Java執行緒池一:執行緒基礎Java執行緒
- MySQL:Innodb purge執行緒略解MySql執行緒
- 多執行緒學習一(多執行緒基礎)執行緒
- MySQL 配置InnoDB的併發執行緒MySql執行緒
- 執行緒基礎執行緒
- java執行緒程式設計(一):執行緒基礎(轉)Java執行緒程式設計
- 程式執行緒篇——程式執行緒基礎執行緒
- 多執行緒程式設計基礎(一)-- 執行緒的使用執行緒程式設計
- MySQL 配置InnoDB主執行緒I/O速率MySql執行緒
- JAVA_基礎多執行緒(一)Java執行緒
- Java 執行緒基礎Java執行緒
- 多執行緒基礎執行緒
- java基礎:執行緒Java執行緒
- Java - 執行緒基礎Java執行緒
- Java 多執行緒基礎(四)執行緒安全Java執行緒
- 多執行緒系列(1),多執行緒基礎執行緒
- 多執行緒系列(三):執行緒池基礎執行緒
- 多執行緒系列(二):多執行緒基礎執行緒
- MySQL 配置後臺InnoDB I/O執行緒數MySql執行緒
- 一. 執行緒管理之Thread基礎執行緒thread
- 多執行緒基礎-基礎實現執行緒
- 解決mysql innodb page corrupt一例MySql
- java - 多執行緒基礎Java執行緒
- 【Java基礎】:執行緒控制Java執行緒
- Java—多執行緒基礎Java執行緒
- java基礎:執行緒同步Java執行緒
- Java 多執行緒基礎(八)執行緒讓步Java執行緒
- iOS開發基礎——執行緒安全(執行緒鎖)iOS執行緒
- python基礎執行緒-管理併發執行緒Python執行緒
- Java 多執行緒基礎(一)基本概念Java執行緒
- (一)基礎篇:速讀Java執行緒池Java執行緒
- 【多執行緒總結(一)-基礎總結】執行緒
- C#多執行緒開發-執行緒基礎 01C#執行緒
- Java 基礎(十四)執行緒——下Java執行緒
- Java基礎之執行緒安全Java執行緒
- 多執行緒基礎入門執行緒
- Java 多執行緒基礎 - CyclicBarrierJava執行緒