MySQL 的數(shù)據(jù)都是存在磁盤中的,那么我們要更新一條記錄的時候,得先要從磁盤讀取該記錄,然后在內(nèi)存中修改這條記錄。那修改完這條記錄是選擇直接寫回到磁盤,還是選擇緩存起來呢?
當然是緩存起來好,這樣下次有查詢語句命中了這條記錄,直接讀取緩存中的記錄,就不需要從磁盤獲取數(shù)據(jù)了。
為此,Innodb 存儲引擎設計了一個緩沖池(Buffer Pool),來提高數(shù)據(jù)庫的讀有了 Buffer Poo 后:
當讀取數(shù)據(jù)時,如果數(shù)據(jù)存在于 Buffer Pool 中,客戶端就會直接讀取 Buffer Pool 中的數(shù)據(jù),否則再去磁盤中讀取。
當修改數(shù)據(jù)時,如果數(shù)據(jù)存在于 Buffer Pool 中,那直接修改 Buffer Pool 中數(shù)據(jù)所在的頁,然后將其頁設置為臟頁(該頁的內(nèi)存數(shù)據(jù)和磁盤上的數(shù)據(jù)已經(jīng)不一致),為了減少磁盤I/O,不會立即將臟頁寫入磁盤,后續(xù)由后臺線程選擇一個合適的時機將臟頁寫入到磁盤。
#Buffer Pool 緩存什么?
InnoDB 會把存儲的數(shù)據(jù)劃分為若干個「頁」,以頁作為磁盤和內(nèi)存交互的基本單位,一個頁的默認大小為 16KB。因此,Buffer Pool 同樣需要按「頁」來劃分。
在 MySQL 啟動的時候,InnoDB 會為 Buffer Pool 申請一片連續(xù)的內(nèi)存空間,然后按照默認的16KB的大小劃分出一個個的頁, Buffer Pool 中的頁就叫做緩存頁。此時這些緩存頁都是空閑的,之后隨著程序的運行,才會有磁盤上的頁被緩存到 Buffer Pool 中。
所以,MySQL 剛啟動的時候,你會觀察到使用的虛擬內(nèi)存空間很大,而使用到的物理內(nèi)存空間卻很小,這是因為只有這些虛擬內(nèi)存被訪問后,操作系統(tǒng)才會觸發(fā)缺頁中斷,申請物理內(nèi)存,接著將虛擬地址和物理地址建立映射關系。
Buffer Pool 除了緩存「索引頁」和「數(shù)據(jù)頁」,還包括了 Undo 頁,插入緩存、自適應哈希索引、鎖信息寫性能。