Buffer?Pool?緩存什么?

Buffer Pool 緩存什么?

InnoDB 會(huì)把存儲(chǔ)的數(shù)據(jù)劃分為若干個(gè)「頁(yè)」,以頁(yè)作為磁盤(pán)和內(nèi)存交互的基本單位,一個(gè)頁(yè)的默認(rèn)大小為 16KB。因此,Buffer Pool 同樣需要按「頁(yè)」來(lái)劃分。


在 MySQL 啟動(dòng)的時(shí)候,InnoDB 會(huì)為 Buffer Pool 申請(qǐng)一片連續(xù)的內(nèi)存空間,然后按照默認(rèn)的16KB的大小劃分出一個(gè)個(gè)的頁(yè), Buffer Pool 中的頁(yè)就叫做緩存頁(yè)。此時(shí)這些緩存頁(yè)都是空閑的,之后隨著程序的運(yùn)行,才會(huì)有磁盤(pán)上的頁(yè)被緩存到 Buffer Pool 中。


所以,MySQL 剛啟動(dòng)的時(shí)候,你會(huì)觀察到使用的虛擬內(nèi)存空間很大,而使用到的物理內(nèi)存空間卻很小,這是因?yàn)橹挥羞@些虛擬內(nèi)存被訪問(wèn)后,操作系統(tǒng)才會(huì)觸發(fā)缺頁(yè)中斷,申請(qǐng)物理內(nèi)存,接著將虛擬地址和物理地址建立映射關(guān)系。


Buffer Pool 除了緩存「索引頁(yè)」和「數(shù)據(jù)頁(yè)」,還包括了 Undo 頁(yè),插入緩存、自適應(yīng)哈希索引、鎖信息等等。


Undo 頁(yè)是記錄什么?


開(kāi)啟事務(wù)后,InnoDB 層更新記錄前,首先要記錄相應(yīng)的 undo log,如果是更新操作,需要把被更新的列的舊值記下來(lái),也就是要生成一條 undo log,undo log 會(huì)寫(xiě)入 Buffer Pool 中的 Undo 頁(yè)面。


查詢(xún)一條記錄,就只需要緩沖一條記錄嗎?


不是的。


當(dāng)我們查詢(xún)一條記錄時(shí),InnoDB 是會(huì)把整個(gè)頁(yè)的數(shù)據(jù)加載到 Buffer Pool 中,將頁(yè)加載到 Buffer Pool 后,再通過(guò)頁(yè)里的「頁(yè)目錄」去定位到某條具體的記錄。


關(guān)于頁(yè)結(jié)構(gòu)長(zhǎng)什么樣和索引怎么查詢(xún)數(shù)據(jù)的問(wèn)題可以在這篇找到答案:換一個(gè)角度看 B+ 樹(shù)


為什么需要 redo log ?

Buffer Pool 是提高了讀寫(xiě)效率沒(méi)錯(cuò),但是問(wèn)題來(lái)了,Buffer Pool 是基于內(nèi)存的,而內(nèi)存總是不可靠,萬(wàn)一斷電重啟,還沒(méi)來(lái)得及落盤(pán)的臟頁(yè)數(shù)據(jù)就會(huì)丟失。


為了防止斷電導(dǎo)致數(shù)據(jù)丟失的問(wèn)題,當(dāng)有一條記錄需要更新的時(shí)候,InnoDB 引擎就會(huì)先把記錄寫(xiě)到 redo log 里面,并更新內(nèi)存,這個(gè)時(shí)候更新就算完成了。同時(shí),InnoDB 引擎會(huì)在適當(dāng)?shù)臅r(shí)候,由后臺(tái)線程將緩存在 Buffer Pool? 的臟頁(yè)刷新到磁盤(pán)里,這就是? WAL (Write-Ahead Logging)技術(shù),指的是 MySQL 的寫(xiě)操作并不是立刻更新到磁盤(pán)上,而是先記錄在日志上,然后在合適的時(shí)間再更新到磁盤(pán)上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容