mysql的刷臟


臟頁:內存數據頁跟磁盤上數據頁內容不一致,將內存頁稱為臟頁

干凈頁:內存數據寫入磁盤后,內存頁跟磁盤頁數據一致,稱內存頁為干凈頁

 

刷臟頁的倆種情況:

1、redo log滿了,這時候系統不能再接受更新了,所有的更新都必須堵住,這時候的更新數為0

2、內純不夠用了,要先將臟頁寫到磁盤。這種情況是常態

innodb用緩沖池(buffer pool)管理內存,緩沖池中的內存頁有三種狀態:

還有沒使用的;innodb的策略是盡量使用內存,對於一個長時間運行的數據庫來說,未被使用的內存頁很少

使用了並且是干凈頁

使用了並且是臟頁

3、數據庫空余的時候

4、mysql正常關閉的時候

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

所以,刷臟頁雖然是常態,但是出現以下這兩種情況,都是會明顯影響性能的:

一個查詢要淘汰的臟頁個數太多,會導致查詢的響應時間明顯變長   #查詢會導致從redo log 將數據flush到磁盤上,然后返回查詢結果

日志寫滿,需要flush到磁盤,這時候更新全部堵住,寫性能跌為 0,這種情況對敏感業務來說,是不能接受的。

 

InnoDB 需要有控制臟頁比例的機制,來盡量避免上面的這兩種情況。

innodb_io_capacity  #告訴innodb磁盤的IO性能為多少,一般設置為磁盤的IOPS

磁盤的 IOPS 可以通過 fio 這個工具來測試
fio -filename=$filename -direct=1 -iodepth 1 -thread -rw=randrw -ioengine=psync -bs=16k -size=500M -numjobs=10 -runtime=10 -group_reporting -name=mytest

 

innodb_io_capacity  設置過小導致的問題: 

數據庫寫入速度很慢,TPS很低,IO壓力卻很小,原因是innodb以為磁盤性能就那么小,刷臟比生產臟頁還慢,臟頁積累,影響查詢更新性能

 

MySQL 中的一個機制,可能讓你的查詢會更慢:

在准備刷一個臟頁的時候,如果這個數據頁旁邊的數據頁剛好是臟頁,就會把這個“鄰居”也帶着一起刷掉;而且這個把“鄰居”拖下水的邏輯還可以繼續蔓延,也就是對於每個鄰居數據頁,如果跟它相鄰的數據頁也還是臟頁的話,也會被放到一起刷。

在 InnoDB 中,innodb_flush_neighbors 參數就是用來控制這個行為的,值為 1 的時候會有上述的“連坐”機制,值為 0 時表示不找鄰居,自己刷自己的。

找“鄰居”這個優化在機械硬盤時代是很有意義的,可以減少很多隨機 IO。機械硬盤的隨機 IOPS 一般只有幾百,相同的邏輯操作減少隨機 IO 就意味着系統性能的大幅度提升。

而如果使用的是 SSD 這類 IOPS 比較高的設備的話,建議把 innodb_flush_neighbors 的值設置成 0。因為這時候 IOPS 往往不是瓶頸,而“只刷自己”,就能更快地執行完必要的刷臟頁操作,減少 SQL 語句響應時間。

在 MySQL 8.0 中,innodb_flush_neighbors 參數的默認值已經是 0 了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM