MySQL臟頁

當(dāng)內(nèi)存數(shù)據(jù)頁跟磁盤數(shù)據(jù)頁內(nèi)容不一致的時(shí)候,我們稱這個(gè)內(nèi)存頁為“臟頁”。內(nèi)存數(shù)據(jù)寫入到磁盤后,內(nèi)存和磁盤上的數(shù)據(jù)頁的內(nèi)容就一致了,稱為“干凈頁”

刷臟頁的時(shí)間

第一種是“redo log寫滿了,要flush臟頁” 整個(gè)系統(tǒng)就不能再接受更新了,所有的更新都必須堵住。如果你從監(jiān)控上看,這時(shí)候更新數(shù)會(huì)跌為0

第二種是“內(nèi)存不夠用了,要先將臟頁寫到磁盤” 這種情況是常態(tài)

InnoDB用緩沖池(buffer pool)管理內(nèi)存,緩沖池中的內(nèi)存頁有三種狀態(tài):

  1. 還沒有使用的;
  2. 使用了并且是干凈頁;
  3. 使用了并且是臟頁。

InnoDB的策略是盡量使用內(nèi)存,因此對于一個(gè)長時(shí)間運(yùn)行的庫來說,未被使用的頁面很少。

當(dāng)要讀入的數(shù)據(jù)頁沒有在內(nèi)存的時(shí)候,就必須到緩沖池中申請一個(gè)數(shù)據(jù)頁。這時(shí)候只能把最久不使用的數(shù)據(jù)頁從內(nèi)存中淘汰掉:如果要淘汰的是一個(gè)干凈頁,就直接釋放出來復(fù)用;但如果是臟頁呢,就必須將臟頁先刷到磁盤,變成干凈頁后才能復(fù)用

一個(gè)查詢要淘汰的臟頁個(gè)數(shù)太多,會(huì)導(dǎo)致查詢的響應(yīng)時(shí)間明顯變長;

第三種是MySQL空閑時(shí)

第四種是MySQL正常關(guān)閉

刷臟頁的控制策略

innodb_io_capacity 它會(huì)告訴InnoDB你的磁盤能力 設(shè)置成磁盤的IOPS

innodb_max_dirty_pages_pct臟頁比例上限,默認(rèn)值是75% 通過Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total得到的

InnoDB的刷盤速度就是要參考這兩個(gè)因素:一個(gè)是臟頁比例,一個(gè)是redo log寫盤速度

刷臟頁的連坐”機(jī)制

一旦一個(gè)查詢請求需要在執(zhí)行過程中先flush掉一個(gè)臟頁時(shí),這個(gè)查詢就可能要比平時(shí)慢了。而MySQL中的一個(gè)機(jī)制,可能讓你的查詢會(huì)更慢:在準(zhǔn)備刷一個(gè)臟頁的時(shí)候,如果這個(gè)數(shù)據(jù)頁旁邊的數(shù)據(jù)頁剛好是臟頁,就會(huì)把這個(gè)“鄰居”也帶著一起刷掉;而且這個(gè)把“鄰居”拖下水的邏輯還可以繼續(xù)蔓延,也就是對于每個(gè)鄰居數(shù)據(jù)頁,如果跟它相鄰的數(shù)據(jù)頁也還是臟頁的話,也會(huì)被放到一起刷

innodb_flush_neighbors 值為1的時(shí)候會(huì)有上述的“連坐”機(jī)制,值為0時(shí)表示不找鄰居,自己刷自己的

找“鄰居”這個(gè)優(yōu)化在機(jī)械硬盤時(shí)代是很有意義的,可以減少很多隨機(jī)IO。機(jī)械硬盤的隨機(jī)IOPS一般只有幾百,相同的邏輯操作減少隨機(jī)IO就意味著系統(tǒng)性能的大幅度提升

使用的是SSD這類IOPS比較高的設(shè)備的話,建議把innodb_flush_neighbors的值設(shè)置成0

在MySQL 8.0中,innodb_flush_neighbors參數(shù)的默認(rèn)值已經(jīng)是0了

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容