MySQL?InnoDB引擎的緩存特性詳解
1. 背景
對(duì)于各種用戶數(shù)據(jù)、索引數(shù)據(jù)等各種數(shù)據(jù)都是需要持久化存儲(chǔ)到磁盤(pán),然后以“頁(yè)”為單位進(jìn)行讀寫(xiě)。
相對(duì)于直接讀寫(xiě)緩存,磁盤(pán)IO的成本相當(dāng)高昂。
對(duì)于讀取的頁(yè)面數(shù)據(jù),并不是使用完就釋放掉,而是放到緩沖區(qū),因?yàn)橄乱淮尾僮饔锌赡苓€需要讀區(qū)該頁(yè)面。
對(duì)于修改過(guò)的頁(yè)面數(shù)據(jù),也不是馬上同步到磁盤(pán),也是放到緩沖區(qū),因?yàn)橄乱淮斡锌赡苓€會(huì)修改該頁(yè)面的數(shù)據(jù)。
但是緩存的空間是有大小限制的,不可能無(wú)限擴(kuò)充。
對(duì)于緩沖區(qū)的數(shù)據(jù),需要有合理的頁(yè)面淘汰算法,將未來(lái)使用概率較小的頁(yè)面釋放或者同步到磁盤(pán),
給當(dāng)下需要存放到緩存的頁(yè)面騰出位置。
2. 存儲(chǔ)器性能差異
寄存器:CPU暫存指令、數(shù)據(jù)的小型存儲(chǔ)區(qū)域,速度快,容量小。
CPU高速緩存(CPU Cache):用于減少CPU訪問(wèn)內(nèi)存所需平均時(shí)間的部件。
內(nèi)存:用于暫時(shí)存放CPU中的運(yùn)算數(shù)據(jù),以及與硬盤(pán)等外部存儲(chǔ)器交換的數(shù)據(jù)。
硬盤(pán):分為固態(tài)硬盤(pán)(SSD)和機(jī)械硬盤(pán)(HHD),是非易失性存儲(chǔ)器。
下圖是各種緩存器的價(jià)格和性能差距,
從下圖可以看出,SSD的隨機(jī)訪問(wèn)延時(shí)在微妙級(jí)別,而內(nèi)存的的隨機(jī)訪問(wèn)延時(shí)在納秒級(jí)別,內(nèi)存比SSD大概快1000倍左右。
3. Buffer Pool
一個(gè)緩沖池(緩沖池)是向操作系統(tǒng)申請(qǐng)的一塊內(nèi)存空間,這塊內(nèi)存空間由多個(gè)chunk組成,每個(gè)chunk均包含多個(gè)控制塊和對(duì)應(yīng)的緩沖頁(yè)。
chunk是向操作系統(tǒng)申請(qǐng)內(nèi)存的最小單位,緩沖頁(yè)大小與InnoDB表空間使用的頁(yè)面大小一致。
Buffer Pool的示意圖如下
每一個(gè)控制塊都對(duì)應(yīng)一個(gè)緩沖頁(yè),控制塊包含該緩沖頁(yè)所屬的表空間編號(hào)、頁(yè)號(hào)、在Buffer Pool中的地址、鏈表結(jié)點(diǎn)信息等等。
當(dāng)剛讀取一個(gè)頁(yè)面時(shí),需要知道緩沖區(qū)有哪些空閑頁(yè)面,當(dāng)修改過(guò)后緩沖頁(yè)后,需要記錄該緩沖頁(yè)需要持久化到磁盤(pán),
當(dāng)緩沖區(qū)沒(méi)有空閑頁(yè)面了,需要有頁(yè)面淘汰算法來(lái)將緩沖頁(yè)移出緩沖區(qū),
以上涉及到Free鏈表、Flush鏈表、LRU鏈表,下面注意說(shuō)明。
4. Free鏈表
Free鏈表是由空閑的緩沖頁(yè)對(duì)應(yīng)的控制塊組成的鏈表,通過(guò)Free鏈表就獲取到空閑的緩沖頁(yè)及其在緩沖區(qū)中的地址。
每當(dāng)需要從磁盤(pán)加載一個(gè)頁(yè)面到緩沖區(qū)時(shí),從該Free鏈表取出一個(gè)控制塊結(jié)點(diǎn),從Free鏈表移除該結(jié)點(diǎn),并加入LRU鏈表。
如果這個(gè)緩沖區(qū)頁(yè)面被修改過(guò),那么會(huì)被加入到Flush鏈表中。
5. Flush鏈表
如果一修改緩沖頁(yè)的數(shù)據(jù)之后就刷新到磁盤(pán),這種頻繁的IO操作勢(shì)必影響程序等整體性能。
試想一下,先后修改1000次同一緩沖區(qū)頁(yè)面的一字節(jié)數(shù)據(jù),每次修改都刷新到磁盤(pán),與修改1000次后再將最終結(jié)果刷新磁盤(pán),節(jié)省了999次刷新磁盤(pán)的操作。
因此,當(dāng)頁(yè)面的數(shù)據(jù)被修改之后,需要將改頁(yè)面放到Flush鏈表,排隊(duì)等候?qū)懭氪疟P(pán)。
這既可以減少在用戶進(jìn)程中刷新磁盤(pán)的次數(shù),也從整體上減少了磁盤(pán)IO到次數(shù)。
6. LRU鏈表
內(nèi)存空間有限,不可能將所有數(shù)據(jù)都緩存在內(nèi)存當(dāng)中,因此需要有一定的算法將內(nèi)存中頁(yè)面淘汰掉(修改過(guò)的頁(yè)面持久化到磁盤(pán))。
LRU(Least Recently Used)鏈表主要用于輔助實(shí)現(xiàn)內(nèi)存頁(yè)面淘汰,故名思義,最先淘汰的是最近最少使用的緩沖頁(yè)。
LRU鏈表的結(jié)果如下圖所示
將LRU鏈表分為young區(qū)域和old區(qū)域。
對(duì)于初次加載到緩沖區(qū)的頁(yè)面,會(huì)放到LRU鏈表old區(qū)域的頭部,這主要避免了預(yù)讀的頁(yè)面被放到了LRU鏈表的首部。
當(dāng)?shù)诙卧L問(wèn)緩沖頁(yè)且時(shí)間間隔超過(guò)innodb_old_blocks_time(默認(rèn)1s)時(shí),才將該頁(yè)面移動(dòng)到LRU鏈表的首部。
進(jìn)一步,為了避免頻繁的移動(dòng)鏈表結(jié)點(diǎn),當(dāng)某個(gè)緩沖頁(yè)已經(jīng)在young區(qū)域的前3/4時(shí),則不會(huì)移動(dòng)該結(jié)點(diǎn)到首部。
7. 其它
如何定位頁(yè)面是否被緩沖呢?
表空間號(hào)和頁(yè)號(hào)可以唯一識(shí)別緩沖頁(yè),因此InnoDB引擎建立了以表空間號(hào)+頁(yè)號(hào)為key,以緩沖頁(yè)控制塊地址為value的哈希表,
從而快速判斷頁(yè)面是否被緩沖,快速定位到數(shù)據(jù)所在地址。
到此這篇關(guān)于MySQL InnoDB引擎的緩存特性詳解的文章就介紹到這了,更多相關(guān)MySQL InnoDB 緩存特性內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mysql觸發(fā)器語(yǔ)法解讀(附帶簡(jiǎn)單實(shí)用例子)
這篇文章主要介紹了Mysql觸發(fā)器語(yǔ)法解讀(附帶簡(jiǎn)單實(shí)用例子),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08mysql自動(dòng)插入百萬(wàn)模擬數(shù)據(jù)的操作代碼
這篇文章主要介紹了mysql自動(dòng)插入百萬(wàn)模擬數(shù)據(jù)的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10mysql利用參數(shù)sql_safe_updates限制update/delete范圍詳解
這篇文章主要給大家介紹了關(guān)于mysql如何利用參數(shù)sql_safe_updates限制update/delete范圍的相關(guān)資料文中介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10MySQL使用UNIQUE實(shí)現(xiàn)數(shù)據(jù)不重復(fù)插入
當(dāng)unique列在一個(gè)UNIQUE鍵上插入包含重復(fù)值的記錄時(shí),我們可以控制MySQL如何處理這種情況:使用IGNORE關(guān)鍵字或者ON DUPLICATE KEY UPDATE子句跳過(guò)INSERT、中斷操作或者更新舊記錄為新值。2017-05-05spark rdd轉(zhuǎn)dataframe 寫(xiě)入mysql的實(shí)例講解
今天小編就為大家分享一篇spark rdd轉(zhuǎn)dataframe 寫(xiě)入mysql的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06MySQL占用內(nèi)存較大與CPU過(guò)高測(cè)試與解決辦法
為了裝mysql環(huán)境測(cè)試,裝上后發(fā)現(xiàn)啟動(dòng)后MySQL占用內(nèi)存了很大,達(dá)8百多兆。網(wǎng)上搜索了一下,得到高人指點(diǎn)my.ini。再也沒(méi)見(jiàn)再詳細(xì)的了..只好打開(kāi)my.ini逐行的啃,雖然英文差了點(diǎn),不過(guò)多少M(fèi)還是看得明的2018-03-03MySql通過(guò)ip地址進(jìn)行訪問(wèn)的方法
這篇文章主要介紹了MySql通過(guò)ip地址進(jìn)行訪問(wèn)的方法,首先要登錄mysql,切換數(shù)據(jù)庫(kù)然后授權(quán),具體代碼詳情大家參考下本文2018-06-06MySQL修改innodb_data_file_path參數(shù)的一些注意事項(xiàng)
這篇文章主要給大家介紹了關(guān)于MySQL修改innodb_data_file_path參數(shù)的一些注意事項(xiàng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04