日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql innodb page_MySQL:Innodb page clean 线程 (一) 基础

發布時間:2023/12/19 数据库 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql innodb page_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

總結

以上是生活随笔為你收集整理的mysql innodb page_MySQL:Innodb page clean 线程 (一) 基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。