帶你了解MySQL中的資料庫緩衝池(Buffer Pool)
對於使用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影片教學】
以上是帶你了解MySQL中的資料庫緩衝池(Buffer Pool)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

MySQL和phpMyAdmin是強大的數據庫管理工具。 1)MySQL用於創建數據庫和表、執行DML和SQL查詢。 2)phpMyAdmin提供直觀界面進行數據庫管理、表結構管理、數據操作和用戶權限管理。

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

在開發一個小型應用時,我遇到了一個棘手的問題:需要快速集成一個輕量級的數據庫操作庫。嘗試了多個庫後,我發現它們要么功能過多,要么兼容性不佳。最終,我找到了minii/db,這是一個基於Yii2的簡化版本,完美地解決了我的問題。

文章摘要:本文提供了詳細分步說明,指導讀者如何輕鬆安裝 Laravel 框架。 Laravel 是一個功能強大的 PHP 框架,它 упростил 和加快了 web 應用程序的開發過程。本教程涵蓋了從系統要求到配置數據庫和設置路由等各個方面的安裝過程。通過遵循這些步驟,讀者可以快速高效地為他們的 Laravel 項目打下堅實的基礎。

MySQL通過表結構和SQL查詢高效管理結構化數據,並通過外鍵實現表間關係。 1.創建表時定義數據格式和類型。 2.使用外鍵建立表間關係。 3.通過索引和查詢優化提高性能。 4.定期備份和監控數據庫確保數據安全和性能優化。

在使用Thelia開發電商網站時,我遇到了一個棘手的問題:MySQL模式設置不當,導致某些功能無法正常運行。經過一番探索,我找到了一個名為TheliaMySQLModesChecker的模塊,它能夠自動修復Thelia所需的MySQL模式,徹底解決了我的困擾。

MySQL是一個開源的關係型數據庫管理系統,廣泛應用於Web開發。它的關鍵特性包括:1.支持多種存儲引擎,如InnoDB和MyISAM,適用於不同場景;2.提供主從復制功能,利於負載均衡和數據備份;3.通過查詢優化和索引使用提高查詢效率。
