您好,登錄后才能下訂單哦!
這篇文章主要介紹“MySQL中的數據庫緩沖池怎么管理”,在日常操作中,相信很多人在MySQL中的數據庫緩沖池怎么管理問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”MySQL中的數據庫緩沖池怎么管理”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
對于使用InnoDB存儲引擎的表來說,是以頁為單位來管理存儲空間的,作為內存和磁盤之間換入換出的基本粒度。當我們將某頁從磁盤中加載到內存中,會進行磁盤I/O。而磁盤I/O的開銷非常影響整體性能,如果我們直接從內存中讀取相應的頁,那豈不是減少了磁盤I/O帶來的性能損耗,效率則會提升很多。基于此,緩沖池(
Buffer Pool
) 出現了,那么接下來,我們就來談談InnoDB中的Buffer Pool。
有人會想,既然緩沖池這么好,那我們將所有數據都存儲到緩沖池中不就好了,不不不,緩沖池是操作系統分配的一片連續的內存。而內存相比于磁盤的容量小得多,并且價格昂貴。那么操作系統會給緩沖池分配多少內存呢?
默認情況下,緩沖池的大小為128MB;
當然,如果你的機器的內存容量非常大,可以在配置文件中配置啟動選項參數innodb_buffer_pool_size
單位是字節,最小不能小于5MB。
緩沖池將操作系統分配的這一片連續的內存,劃分成若干個大小默認為16KB的頁(緩沖頁)【此時還沒有真正的磁盤頁被緩存到Buffer Pool中】,當我們從磁盤中換入一個頁到緩沖池中,如何分配位置呢?因此就需要一些控制信息來標識這些緩沖池中的緩沖頁,這些控制信息都存放在一個叫控制塊的內存區域中,與緩沖頁一一對應。控制塊的大小也是固定的。因此在這片連續的內存空間中,難免會產生內存碎片。綜上,緩沖池的內部結構如下:
緩沖頁
控制塊:頁號、緩沖頁在緩沖池中的地址、鏈表節點信息等。
內存碎片【若內存分配得當,內存碎片可有可無】
上面在控制塊中提到了鏈表節點信息,那么鏈表節點是用來做什么的呢?是為了更好的管理緩沖池中的頁。而鏈表就是用來鏈接控制塊的,因為控制塊與緩沖頁是一一對應的。
將所有空閑的緩沖頁對應的控制塊鏈接起來,形成的鏈表。
解決的問題:從磁盤中換入一個頁到緩沖池中,如何區分緩沖池中的哪個頁是空閑的呢?而有了空閑鏈表之后,換入一個磁盤頁到緩沖池中時,就直接從空閑鏈表中獲取一個空閑的緩沖頁,并將磁盤頁中對應的信息填到緩沖頁對應的控制塊中,然后將該控制塊從空閑鏈表中刪除即可。
若修改了緩沖池中的緩沖頁的數據,導致其與磁盤中數據不一致,該頁稱為臟頁。將所有臟頁對應的控制塊鏈接起來形成更新鏈表,在將來的某個時間根據該鏈表將對應緩存頁的數據刷新到磁盤中。
緩沖池的大小是有限的,如果緩存的頁超出了緩沖池的大小,即沒有空閑的緩沖頁了,當有新的頁要添加到緩沖池中時,采取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鏈表頭部
那么為什么InnoDB不使用這么直觀的LRU算法呢?原因如下:
預讀失效
預讀到緩沖池中的頁都會放到LRU鏈表的頭部,但其中很多頁可能并不會被讀取。
緩沖池污染
很多使用頻率較低的頁加載到緩沖池中,會把使用頻率較高的頁從緩沖池中淘汰掉。比如全表掃描
基于上述缺點,優化后的具體方法將傳統LRU鏈表劃分為兩部分:熱數據區域【年輕區】&冷數據區域【老年區】
熱數據區域【年輕區】:使用頻率高的緩沖頁
冷數據區域【老年區】:使用頻率低的區域
結構簡圖如下所示:
如圖所示,熱數據區域與冷數據區域分別占用不同比例,那么我們可以通過innodb_old_blocks_pct
啟動選項來控制冷數據區域所占比例。
改進后的LRU如何更好的解決預讀失效問題呢?
某個頁在初次加載到緩沖池中時,先淘汰掉冷數據區域尾部的控制塊(即其對應的頁淘汰掉),然后新頁對應的控制塊會先放到冷數據區域的頭部。
若后續該頁不被進行訪問就會慢慢從冷數據區域中被淘汰掉,總體不會影響熱數據區域訪問頻繁的緩沖頁。
改進后的LRU如何更好的解決緩沖池污染問題呢?
先說結論,并沒有很好的優化這個問題,原因如下【以全表掃描為例】:
某個初次訪問的頁同樣會放到冷數據區域的頭部,但后續訪問又會將其放到熱數據區域的頭部,這樣同樣會把訪問頻率較高的頁給擠掉。
那么到底該如何解決緩沖池污染問題呢?
緩沖池引入了冷數據區域時間窗口機制,即只有后續訪問該頁與第一訪問該頁的時間間隔大于規定的窗口值,就會將該頁從冷數據區域移到熱數據區域的頭部。小于規定的窗口值,就不會進行移動操作。
同樣,窗口值可通過innodb_old_blocks_time
參數【單位ms】來設置,默認1000ms,而1s會篩選掉大部分像全表掃描這樣的操作。比如在一次全表掃描過程中,多次訪問一個頁面的時間間隔不會超過1s。
緩沖池和查詢緩存是一個東西嗎?→不是
緩沖池會盡量將經常使用的數據保存起來,在MySQL進行頁面讀操作的時候,首先會判斷該頁面是否在緩沖池中,如果存在就直接讀取,如果不存在,就會通過內存或磁盤將頁面存放到緩沖池中再進行讀取。
查詢緩存是提前把查詢結果緩存起來,這樣下次不需要執行就可以直接拿到結果。需要說明的是,在MySQL中的查詢緩存,不是緩存查詢計劃,而是查詢對應的結果。命中條件苛刻,而且只要數據表發生變化,查詢緩存就會失效,因此命中率低。
到此,關于“MySQL中的數據庫緩沖池怎么管理”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。