周末在一臺MySQL實例上頻繁做大批量的寫入測試,無意中發現MySQL的errorlog中頻繁出現如下的Note:page_cleaner: 1000ms intended loop took **** ms. The settings might not be optimal. (flushed= ...
周末在一臺MySQL實例上頻繁做大批量的寫入測試,無意中發現MySQL的errorlog中頻繁出現如下的Note:
page_cleaner: 1000ms intended loop took **** ms. The settings might not be optimal. (flushed=**** and evicted=0, during the time.)
一個典型的信息如下
InnoDB: page_cleaner: 1000ms intended loop took 4068ms. The settings might not be optimal. (flushed=2000 and evicted=0, during the time.)
該告警意味著MySQL實例按照目前IO相關的參數配置的前提下,存在著IO寫入性能上的瓶頸,配置參數與IO處理能力不匹配。
因為很清楚是在做測試的情況下,連續大批量寫入數據造成的,很有可能是checkpoint刷新臟頁造成IO不足的警告。
MySQL在正常運行時4個與IO寫入(checkpoint)相關的參數,然後逐一分析其寫入的時機和寫入臟頁的數量。
1,innodb_io_capacity
master thread中每秒或者每10s迴圈中刷新臟頁的數量
那麼master thread中定時迴圈刷新臟頁的數據是多少?由參數innodb_io_capacity決定,以下截圖自《MySQL技術內幕InnoDB存儲引擎》page 41
2,innodb_max_dirty_pages_pct
innodb buffer pool中臟頁數量超過這個比例之後,刷新部分臟頁到磁碟。
這種情況下刷新的“部分”臟頁,到底是刷新多少個臟頁?
因為沒有閱讀源碼的能力,從這裡來看(後面會給出參考鏈接),這個值是依舊是innodb_io_capacity個臟頁。
innodb_max_dirty_pages_pct這個參數本身(75%)預設值差不多就是最優化的,應該是不能瞎調的。以下截圖自《MySQL技術內幕InnoDB存儲引擎》page 42
3,innodb_lru_scan_depth
lru列表中保持空閑page的數據量,如果低於這個數量,則按照LRU的原則刷新臟頁到磁碟。
這種情況下是刷線多少個臟頁?
此情況下觸發,預設掃描innodb_lru_scan_depth個lru冷端數據頁,將臟頁寫入磁碟(有10個就刷10,有100個就刷100個……)
這一點參考這個(筆者並沒有找到確切的證據):https://www.cnblogs.com/geaozhang/p/7341333.html
4,redo log日誌空間達到配置閾值的刷新(一個實例的redo log空間總和)
單個redo log大小的參數:innodb_log_file_size
redo log 個數:innodb_log_files_in_group
async_water_mark = 75%*innodb_log_file_size
sync_water_mark = 90%*innodb_log_file_size
1)當checkpoint_age<sync_water_mark的時候,無需執行Flush checkpoint。也就說,redo log剩餘空間超過25%的時候,無需執行Async/Sync Flush checkpoint。
2)當async_water_mark<checkpoint_age<sync_water_mark的時候,執行Async Flush checkpoint,也就說,redo log剩餘空間不足25%,但是大於10%的時候,執行Async Flush checkpoint,刷新到滿足條件1
3)當checkpoint_age>sync_water_mark的時候,執行sync Flush checkpoint。也就說,redo log剩餘空間不足10%的時候,執行Sync Flush checkpoint,刷新到滿足條件1。
在buffer pool遠沒有達到分配值的情況下,innodb_max_dirty_pages_pct和innodb_lru_scan_depth也不會達到checkpoint的條件,redo log也沒有切換,
因此只能斷定為master thread 後臺線程定時刷新臟頁造成的IO負擔過載,因此嘗試 set global innodb_io_capacity = 1000;
經後繼續測試觀察,尚未發現類似新的page_cleaner告警日誌產生。
參考:
http://blog.itpub.net/26506993/viewspace-2214703/
https://www.cnblogs.com/geaozhang/p/7341333.html
https://www.jianshu.com/p/6991304a8e26?tdsourcetag=s_pcqq_aiomsg
https://www.jianshu.com/p/ddb24f9afae0?tdsourcetag=s_pcqq_aiomsg