久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL中的數據庫緩沖池怎么管理

162次閱讀
沒有評論

共計 3046 個字符,預計需要花費 8 分鐘才能閱讀完成。

這篇文章主要介紹“MySQL 中的數據庫緩沖池怎么管理”,在日常操作中,相信很多人在 MySQL 中的數據庫緩沖池怎么管理問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”MySQL 中的數據庫緩沖池怎么管理”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!

對于使用 InnoDB 存儲引擎的表來說,是以頁為單位來管理存儲空間的,作為內存和磁盤之間換入換出的基本粒度。當我們將某頁從磁盤中加載到內存中,會進行磁盤 I /O。而磁盤 I / O 的開銷非常影響整體性能,如果我們直接從內存中讀取相應的頁,那豈不是減少了磁盤 I / O 帶來的性能損耗,效率則會提升很多。基于此,緩沖池(Buffer Pool)出現了,那么接下來,我們就來談談 InnoDB 中的 Buffer Pool。

緩沖池(Buffer Pool)

有人會想,既然緩沖池這么好,那我們將所有數據都存儲到緩沖池中不就好了,不不不,緩沖池是操作系統分配的一片連續的內存。而內存相比于磁盤的容量小得多,并且價格昂貴。那么操作系統會給緩沖池分配多少內存呢?

默認情況下,緩沖池的大小為 128MB;

當然,如果你的機器的內存容量非常大,可以在配置文件中配置啟動選項參數 innodb_buffer_pool_size 單位是字節,最小不能小于 5MB。

緩沖池的內部結構

緩沖池將操作系統分配的這一片連續的內存,劃分成若干個大小默認為 16KB 的頁(緩沖頁)【此時還沒有真正的磁盤頁被緩存到 Buffer Pool 中】,當我們從磁盤中換入一個頁到緩沖池中,如何分配位置呢?因此就需要一些控制信息來標識這些緩沖池中的緩沖頁,這些控制信息都存放在一個叫控制塊的內存區域中,與緩沖頁一一對應。控制塊的大小也是固定的。因此在這片連續的內存空間中,難免會產生內存碎片。綜上,緩沖池的內部結構如下:

緩沖頁

控制塊:頁號、緩沖頁在緩沖池中的地址、鏈表節點信息等。

內存碎片【若內存分配得當,內存碎片可有可無】

緩沖池的管理

上面在控制塊中提到了鏈表節點信息,那么鏈表節點是用來做什么的呢?是為了更好的管理緩沖池中的頁。而鏈表就是用來鏈接控制塊的,因為控制塊與緩沖頁是一一對應的。

1)空閑鏈表

將所有空閑的緩沖頁對應的控制塊鏈接起來,形成的鏈表。

解決的問題:從磁盤中換入一個頁到緩沖池中,如何區分緩沖池中的哪個頁是空閑的呢?而有了空閑鏈表之后,換入一個磁盤頁到緩沖池中時,就直接從空閑鏈表中獲取一個空閑的緩沖頁,并將磁盤頁中對應的信息填到緩沖頁對應的控制塊中,然后將該控制塊從空閑鏈表中刪除即可。

2)更新鏈表

若修改了緩沖池中的緩沖頁的數據,導致其與磁盤中數據不一致,該頁稱為臟頁。將所有臟頁對應的控制塊鏈接起來形成更新鏈表,在將來的某個時間根據該鏈表將對應緩存頁的數據刷新到磁盤中。

3)LRU 鏈表

緩沖池的大小是有限的,如果緩存的頁超出了緩沖池的大小,即沒有空閑的緩沖頁了,當有新的頁要添加到緩沖池中時,采取 LRU 的策略將舊的緩沖頁從緩沖池中移除,然后將新的頁添加進來。由于 LRU 鏈表涉及的內容較多,我們接下來單獨介紹。

LRU 鏈表所蘊含的“哲理”先提一下預讀機制

在 I / O 上的優化機制,預讀顧名思義,會異步地把某些頁面加載到緩沖池中,預計很快就會需要這些頁面,這些請求在一個范圍內引入所有頁面,就是所謂的 局部性原理,目的是減少磁盤 I /O。

了解預讀機制之前,先回顧一下 InnoDB 邏輯存儲單元:表空間(tablespace)→段(segment)→區(extent)→頁(page)。其中特意提一下區,后面會用到:一個區就是物理位置上連續的 64 個頁,即一個區的大小是 1MB.

預讀機制可以細分為以下兩種:

Linear read-ahead(線性預讀):一種基于按順序訪問的緩沖池中的頁面來預測可能很快需要哪些頁面的技術。通過配置參數 innodb_read_ahead_threshold,若順序訪問的某個區的頁面超過這個參數的值,會觸發異步讀請求來讀取下一個區中全部的頁面到緩沖池中。

Random read-ahead(隨機預讀):可以根據緩沖池中已經存在的頁面預測何時可能需要頁面,而不管這些頁面的讀取順序如何。如果在緩沖池中發現同一個區段的 13 個連續頁面,InnoDB 會異步發出一個請求來預取該區段的剩余頁面。通過配置變量 innodb_random_read_ahead 來控制隨機讀的。

傳統 LRU 對緩沖頁是如何管理的呢?

利用 LRU 算法對最近最少使用的緩沖頁進行管理,形成對應的鏈表,方便用于淘汰。

當訪問一個頁【即最近訪問】

該頁在緩沖池中,將對應控制塊移至 LRU 鏈表頭部

該頁不在緩沖池中,淘汰尾部最近最少使用的頁,從磁盤中加載進來該頁并放在 LRU 鏈表頭部

那么為什么 InnoDB 不使用這么直觀的 LRU 算法呢?原因如下:

預讀失效

預讀到緩沖池中的頁都會放到 LRU 鏈表的頭部,但其中很多頁可能并不會被讀取。

緩沖池污染

很多使用頻率較低的頁加載到緩沖池中,會把使用頻率較高的頁從緩沖池中淘汰掉。比如全表掃描

優化后的 LRU 對緩沖頁是如何管理的呢?

基于上述缺點,優化后的具體方法將傳統 LRU 鏈表劃分為兩部分:熱數據區域【年輕區】冷數據區域【老年區】

熱數據區域【年輕區】:使用頻率高的緩沖頁

冷數據區域【老年區】:使用頻率低的區域

結構簡圖如下所示:

如圖所示,熱數據區域與冷數據區域分別占用不同比例,那么我們可以通過 innodb_old_blocks_pct 啟動選項來控制冷數據區域所占比例。

改進后的 LRU 如何更好的解決預讀失效問題呢?

某個頁在初次加載到緩沖池中時,先淘汰掉冷數據區域尾部的控制塊(即其對應的頁淘汰掉),然后新頁對應的控制塊會先放到冷數據區域的頭部。

若后續該頁不被進行訪問就會慢慢從冷數據區域中被淘汰掉,總體不會影響熱數據區域訪問頻繁的緩沖頁。

改進后的 LRU 如何更好的解決緩沖池污染問題呢?

先說結論,并沒有很好的優化這個問題,原因如下【以全表掃描為例】:

某個初次訪問的頁同樣會放到冷數據區域的頭部,但后續訪問又會將其放到熱數據區域的頭部,這樣同樣會把訪問頻率較高的頁給擠掉。

那么到底該如何解決緩沖池污染問題呢?

緩沖池引入了冷數據區域時間窗口機制,即只有后續訪問該頁與第一訪問該頁的時間間隔大于規定的窗口值,就會將該頁從冷數據區域移到熱數據區域的頭部。小于規定的窗口值,就不會進行移動操作。

同樣,窗口值可通過 innodb_old_blocks_time 參數【單位 ms】來設置,默認 1000ms,而 1s 會篩選掉大部分像全表掃描這樣的操作。比如在一次全表掃描過程中,多次訪問一個頁面的時間間隔不會超過 1s。

緩沖池 VS 查詢緩存

緩沖池和查詢緩存是一個東西嗎?→不是

緩沖池會盡量將經常使用的數據保存起來,在 MySQL 進行頁面讀操作的時候,首先會判斷該頁面是否在緩沖池中,如果存在就直接讀取,如果不存在,就會通過內存或磁盤將頁面存放到緩沖池中再進行讀取。

查詢緩存是提前把查詢結果緩存起來,這樣下次不需要執行就可以直接拿到結果。需要說明的是,在 MySQL 中的查詢緩存,不是緩存查詢計劃,而是查詢對應的結果。命中條件苛刻,而且只要數據表發生變化,查詢緩存就會失效,因此命中率低。

到此,關于“MySQL 中的數據庫緩沖池怎么管理”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-13發表,共計3046字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 奇台县| 任丘市| 濮阳县| 明光市| 驻马店市| 夏河县| 瓦房店市| 南雄市| 洛阳市| 成武县| 遵义市| 凤山县| 崇明县| 社会| 普宁市| 南康市| 内丘县| 犍为县| 河津市| 高密市| 赤城县| 鄢陵县| 永兴县| 青铜峡市| 咸宁市| 来安县| 寿光市| 田东县| 永兴县| 布拖县| 荔波县| 博客| 贵定县| 绥宁县| 齐河县| 福鼎市| 勃利县| 财经| 英德市| 屏东市| 尼木县|