1. 程式人生 > >面試題:瞭解MySQL的Flush-List嗎?順便說一下髒頁的落盤機制!(文末送書)

面試題:瞭解MySQL的Flush-List嗎?順便說一下髒頁的落盤機制!(文末送書)

Hi,大家好!我是白日夢! 今天我要跟你分享的MySQL話題是:“瞭解Flush-List嗎?順便說一下髒頁的落盤機制!(文末送書)” 本文是MySQL專題的第 8 篇,共110篇。
### 一、回顧 現在稍微回顧一下:前面幾篇文章介紹了LRU List、Free List。 MySQL啟動後Buffer Pool會初始化。Buffer Pool也會初始化好N多個空白的快取頁,以及它們的描述資料會被組織成LRU連結串列以及FreeList 雙向連結串列。 這時你從磁碟中讀取一個數據頁,會先從Free List中找出一個空閒快取頁的描述資訊,然後將你讀出的資料頁中載入進快取頁中。同時將快取頁的描述資訊從Free List中剔除,此外該描述資訊塊還會被維護進LRU連結串列中。 資料頁被載入進Buffer Pool後你就可以對其進行變更操作了。
### 二、Flush List 為了加快響應客戶端的速度,MySQL會在Buffer Pool中對資料進行修改,可是一旦你對LRU連結串列中的快取頁做了修改,那該頁中的資料和磁碟中的資料頁資訊就不一致了!大家一般管這種資料頁叫做髒頁。 為了保證資料的最終一致性,MySQL是需要將髒頁重新整理回磁碟的!

但是問題是:需要將哪些資料頁重新整理回磁碟呢? 這就引出了Flush List~ Flush List 和 Free List很像,都是由Buffer Pool中資料描述資訊組織而成的雙向連結串列。 ![](https://img2020.cnblogs.com/blog/1496926/202011/1496926-20201118095229120-1274773833.jpg) **一旦**你對記憶體中的緩衝頁作出了修改,那該緩衝頁對應的描述資訊塊**就會**新增進 Flush List。這樣當Buffer Pool中的資料頁不夠用時,我們就可以優先將 Flush List中的髒資料頁重新整理進磁碟中。 如果你讀了前幾篇文章那你肯定知道了 LRUList、FreeList、FlushList、Buffer Pool、髒頁、髒資料。 下面乘勝追擊!一起看一下髒頁的落盤機制
### 三、什麼是髒頁?什麼是髒資料? - 什麼是髒頁? 我在介紹Flush List 的那篇文章有提及,髒頁就是LRU連結串列中被修改了的快取頁。他們和磁碟中的資料頁不一致,髒頁是需要被重新整理回磁碟的。 - 什麼是髒資料? 這個問題其實引出了髒讀的概念。舉個例子:事物A中讀取到了事物B中未提交的資料,我們管這些資料叫做髒資料。
### 四、髒頁刷回磁碟的時機 當Buffer Pool不夠用時,根據LRU機制,MySQL會將Old SubList部分的快取頁移出LRU連結串列。如果被移除出去的快取頁的描述資訊在Flush List中,MySQL就得將其重新整理回磁碟。

InnoDB儲存引擎將髒頁刷回磁碟的時機有蠻多的,你可以把它當作拓展知識大概瀏覽一下。 1、當MySQL資料庫關閉時,會將所有的髒資料頁重新整理回磁碟。這個功能由引數:`innodb_fast_shutdown=0`控制,預設讓InnoDB在關閉前將髒頁刷回磁碟,以及清理掉undo log。 2、有一個後臺執行緒Master Thread會按照每秒或者每十秒的速度,非同步的將Buffer Pool中一定比例的頁面重新整理回磁碟中。 3、在MySQL5.7中,Buffer Pool的重新整理由page cleaner threads完成。 - 我們可以通過`innodb_page_cleaners`引數控制page cleaner threads執行緒的數量,但是當你將這個數值調整的比Buffer Pool的數量還大時,MySQL會自動將 `innodb_page_cleaners`數量設定為`innodb_buffer_pool_instances`的數量。 - Innodb1.1.x之前需要保證LRU列表中有至少100個空閒頁可以使用。低於這個閾值就會觸發髒頁的重新整理。 - 從MySQL5.6,也就是innodb1.2.X開始,`innodb_lru_scan_depth`引數為每個緩衝池例項指定page cleaner threads 掃描Buffer Pool來查詢要重新整理的髒頁的下行距離。預設為1024,該後臺執行緒每秒都會執行一次。 4、當髒資料頁太多時,也會觸發將髒資料頁重新整理回磁碟。該機制可由引數`innodb_nax_dirty_pages_pct`控制,比如將其設定為75,表示,當Buffer Pool中的髒資料頁達到整體快取的75%時,觸發重新整理的動作。現實情況是該引數預設值為0。以此來禁用Buffer Pool早期的重新整理行為。 5、當redo log不可用時,也會強制髒頁列表中的髒頁重新整理回磁碟。這個機制同樣由一個後臺執行緒完成。
### 六、其他關於髒頁重新整理的知識點 重新整理臨接資料頁:意思是當MySQL將某髒頁重新整理回磁碟時,是否也以相同的態度將該髒頁鄰接的髒頁一併重新整理回磁碟。 可以通過引數`innodb_flush_neighbors`控制該過程。 - 設定為0時表示,禁用重新整理鄰接的功能。 - 設定為1時表示,以相同的態度重新整理其鄰接的髒頁。 - 設定為2時表示,以相同的程度重新整理髒頁。 那如何選擇將其設定為哪種狀態呢? 你可以根據MySQL例項所在機器的儲存型別來決定。如果為HDD儲存建議將其開啟,因為HDD的磁碟重新整理速率較低,開啟該引數後可以有效的減少IO操作。相反如果使用SSD儲存,其本身就有高磁碟IO的特性,建議禁用該引數。
### 七、推薦閱讀 [1、談談MySQL中基數是什麼?](http://mp.weixin.qq.com/s?__biz=MzI5MDg4ODEzOA==&mid=2247483722&idx=1&sn=4d1e1eb5e4f97c8a91898195823eb26b&chksm=ec1841efdb6fc8f9429609c18270fd421c61e442ebc893c4fa00ea29df12c73748e1f64ed54e&scene=21#wechat_redirect) [2、聊聊什麼是慢查?如何監控?如何排查?](http://mp.weixin.qq.com/s?__biz=MzI5MDg4ODEzOA==&mid=2247483764&idx=1&sn=332b5b05d931b06a64ab07982bfab794&chksm=ec1841d1db6fc8c732c1c78fce4f9027305fd2590871038817f8386b5fc0b4a3e296b4970d30&scene=21#wechat_redirect) [3、對Not Null欄位插入Null值有啥現象?](http://mp.weixin.qq.com/s?__biz=MzI5MDg4ODEzOA==&mid=2247483766&idx=1&sn=0f53c86b270183e24134b8b3eac71cd6&chksm=ec1841d3db6fc8c553e882d33c2cfc83bc8fc7d5046fbc7ee147bfff3403ec36a1c24094067a&scene=21#wechat_redirect) [4、能談談year、date、datetime、time、timestamp的區別嗎?](http://mp.weixin.qq.com/s?__biz=MzI5MDg4ODEzOA==&mid=2247483802&idx=1&sn=0714dea1bf86ea9f1e44b0eb377b1d1e&chksm=ec18413fdb6fc829fb1285d9142f8f8daccc35b4cb5de47c0f9ef2d5efb5fc8db1bc8f6d5a08&scene=21#wechat_redirect) [5、你有沒有搞混查詢快取和Buffer Pool?談談看!](http://mp.weixin.qq.com/s?__biz=MzI5MDg4ODEzOA==&mid=2247483817&idx=1&sn=d19e5ce05cd9520d1becd7b6afa5e0be&chksm=ec18410cdb6fc81a2bc86184427536832c8f8aff1daae1d1966afa0ff1af667d292ffe43a310&scene=21#wechat_redirect) [6、你知道資料庫緩衝池中的LRU-List嗎?](http://mp.weixin.qq.com/s?__biz=MzI5MDg4ODEzOA==&mid=2247483875&idx=1&sn=60744026b460f40e95871b0ddb0b8eab&chksm=ec184146db6fc85009bf60c6561e6d09086a2ca901f6e808a7525d6f2ed441bbc20aaeeab1a4&scene=21#wechat_redirect) [7、瞭解InnoDB的FreeList嗎?談談看!](http://mp.weixin.qq.com/s?__biz=MzI5MDg4ODEzOA==&mid=2247483877&idx=1&sn=55af9ab7e9a92891bc5c79d80f4d70f8&chksm=ec184140db6fc856cfdf5f9b4eaed27503f91da810d0c39f27b84ec122d770d85af3fb64c84e&scene=21#wechat_redirect)
參考: https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool-flushing.html https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_lru_scan_depth 《MySQL技術內幕》
### 關注送書!《Netty實戰》

文章公號 首發!連載中!關注微信公號回覆:“抽獎” 還可參加抽