欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySql?InnoDB存儲(chǔ)引擎之Buffer?Pool運(yùn)行原理講解

 更新時(shí)間:2023年01月04日 14:09:14   作者:程序員小潘  
緩沖池是用于存儲(chǔ)InnoDB表,索引和其他輔助緩沖區(qū)的緩存數(shù)據(jù)的內(nèi)存區(qū)域。緩沖池的大小對(duì)于系統(tǒng)性能很重要。更大的緩沖池可以減少磁盤(pán)I/O來(lái)多次訪問(wèn)同一表數(shù)據(jù)。在專(zhuān)用數(shù)據(jù)庫(kù)服務(wù)器上,可以將緩沖池大小設(shè)置為計(jì)算機(jī)物理內(nèi)存大小的百分之80

1. 前言

我們已經(jīng)知道,對(duì)于InnoDB存儲(chǔ)引擎而言,頁(yè)是磁盤(pán)和內(nèi)存交互的基本單位。哪怕你要讀取一條記錄,InnoDB也會(huì)將整個(gè)索引頁(yè)加載到內(nèi)存。哪怕你只改了1個(gè)字節(jié)的數(shù)據(jù),該索引頁(yè)就是臟頁(yè)了,整個(gè)索引頁(yè)都要刷新到磁盤(pán)。InnoDB是基于磁盤(pán)的存儲(chǔ)引擎,如果每次操作都去讀寫(xiě)磁盤(pán),那么性能將會(huì)受到很大的影響。而且絕大多數(shù)時(shí)候,程序讀寫(xiě)的數(shù)據(jù)在磁盤(pán)上并不是連續(xù)的,這意味著需要執(zhí)行大量的隨機(jī)IO讀寫(xiě),磁盤(pán)隨機(jī)IO讀寫(xiě)效率是非常低的,尤其是傳統(tǒng)的機(jī)械硬盤(pán)。

在解決這個(gè)問(wèn)題之前,大家可以先想一想,為什么我們只想讀取一條記錄,而InnoDB會(huì)將整個(gè)頁(yè)的數(shù)據(jù)都加載到內(nèi)存?因?yàn)楦鶕?jù)計(jì)算機(jī)的局部性原理,程序接下來(lái)大概率會(huì)訪問(wèn)與它相鄰的記錄,為了避免頻繁發(fā)起磁盤(pán)IO讀操作,InnoDB直接將整個(gè)頁(yè)都加載到內(nèi)存,下次再訪問(wèn)頁(yè)中的其它記錄時(shí),就可以命中緩存了,減少磁盤(pán)IO操作。

問(wèn)題解決的思路其實(shí)是一樣的,磁盤(pán)的速度雖然很慢,但是內(nèi)存的速度快啊。這些被加載到內(nèi)存里的索引頁(yè),使用完畢后不要立即釋放,而是將它們先緩存下來(lái),下次再訪問(wèn)這些頁(yè)時(shí),就可以命中緩存了,減少磁盤(pán)IO,從而提升性能。理論上,只要內(nèi)存無(wú)限大,那么MySQL幾乎可以是基于內(nèi)存的數(shù)據(jù)庫(kù)了。

InnoDB緩存索引頁(yè)的組件,就是我們今天要聊的「Buffer Pool」。

2. Buffer Pool

MySQL服務(wù)器啟動(dòng)時(shí),InnoDB會(huì)向操作系統(tǒng)申請(qǐng)一塊連續(xù)的內(nèi)存空間用來(lái)緩存索引頁(yè),這一塊連續(xù)的內(nèi)存空間就是Buffer Pool。默認(rèn)情況下Buffer Pool的大小是128MB,查看命令如下:

mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+

理論上,Buffer Pool越大,緩存的索引頁(yè)就可以更多,緩存的命中率就可以更高,對(duì)應(yīng)的性能提升就越明顯。如果你的機(jī)器內(nèi)存夠大,完全可以調(diào)大 Buffer Pool的大小,在配置文件里進(jìn)行修改:

[server]
innodb_buffer_pool_size=2147483648
innodb_buffer_pool_instances=2

Buffer Pool最小是5MB,即使你配置的小于5MB,InnoDB也會(huì)分配5MB的內(nèi)存。

innodb_buffer_pool_instances啟動(dòng)項(xiàng)代表Buffer Pool實(shí)例的個(gè)數(shù)。是的,你沒(méi)看錯(cuò),Buffer Pool支持配置多個(gè),不同實(shí)例之間是隔離的,互不影響。配置多個(gè)的主要原因是因?yàn)锽uffer Pool由多個(gè)鏈表組成,在維護(hù)這些鏈表時(shí)需要加鎖保證同步,在高并發(fā)場(chǎng)景下會(huì)影響性能,配置多個(gè)實(shí)例就可以解決這個(gè)問(wèn)題了。

每個(gè)Buffer Pool的大小是innodb_buffer_pool_size/innodb_buffer_pool_instances,InnoDB有規(guī)定,單個(gè)Buffer Pool實(shí)例的大小如果小于1GB,即使配置多個(gè)也不會(huì)生效。

2.1 Buffer Pool結(jié)構(gòu)

Buffer Pool是用來(lái)緩存物理磁盤(pán)上的頁(yè)結(jié)構(gòu)的,那它自然也是由若干個(gè)頁(yè)組成。為了與磁盤(pán)上的頁(yè)區(qū)分開(kāi),這里我們叫它「緩沖頁(yè)」。為了更好的管理這些緩沖頁(yè),InnoDB為每個(gè)緩沖頁(yè)都創(chuàng)建了一個(gè)「控制塊」對(duì)象與之關(guān)聯(lián)。所以,Buffer Pool其實(shí)是由若干對(duì)控制塊和緩沖頁(yè),以及一些碎片空間組成的。

為什么會(huì)有碎片空間?如果最后剩余的空間不足以分配一對(duì)控制塊和緩沖頁(yè),就會(huì)被浪費(fèi)掉,也就是碎片空間。除非你把Buffer Pool的大小設(shè)置的剛好合適。另外,控制塊的大小在正常模式下和DEBUG模式下占用的大小并不一樣,DEBUG模式下控制塊的大小約為緩沖頁(yè)的5%。

緩沖頁(yè)的結(jié)構(gòu)和物理磁盤(pán)上的頁(yè)一致,也就沒(méi)什么好說(shuō)的了。控制塊主要記錄了緩沖頁(yè)所屬的表空間ID、頁(yè)號(hào)、緩沖頁(yè)在Buffer Pool中的地址、鏈表節(jié)點(diǎn)信息等等。我們重點(diǎn)關(guān)注鏈表節(jié)點(diǎn),因?yàn)锽uffer Pool出于不同的目的,將這些緩沖頁(yè)串聯(lián)成了多條鏈表,后面會(huì)提到。

總之,Buffer Pool的結(jié)構(gòu)其實(shí)很簡(jiǎn)單,如下圖所示:

2.2 Free鏈表

Buffer Pool是用來(lái)緩存磁盤(pán)上的頁(yè)結(jié)構(gòu)的,那么第一個(gè)問(wèn)題就來(lái)了。當(dāng)我們要從磁盤(pán)上加載一個(gè)頁(yè)的時(shí)候,這個(gè)頁(yè)該放到Buffer Pool的哪個(gè)緩沖頁(yè)里呢?總不能遍歷整個(gè)Buffer Pool吧,哪個(gè)緩沖頁(yè)是空閑的就直接使用它,這未免也太笨拙了。

InnoDB會(huì)通過(guò)控制塊里的鏈表節(jié)點(diǎn)屬性,將所有空閑的緩沖頁(yè)都串聯(lián)成一條雙向鏈表,叫作「Free鏈表」。MySQL服務(wù)器剛啟動(dòng)時(shí),所有的緩沖頁(yè)都會(huì)加入到該鏈表中,因?yàn)樗械木彌_頁(yè)都沒(méi)有被使用。當(dāng)我們要把磁盤(pán)上的頁(yè)加載到內(nèi)存時(shí),就從Free鏈表申請(qǐng)一個(gè)緩沖頁(yè),并把它對(duì)應(yīng)的控制塊從Free鏈表中移除,這比遍歷整個(gè)Buffer Pool可高效多了。

怎么找到Free鏈表呢?為了更好的管理這些鏈表,InnoDB為每條鏈表都創(chuàng)建了一個(gè)叫作「鏈表基節(jié)點(diǎn)」的結(jié)構(gòu),它的屬性就三個(gè),分別記錄鏈表的頭尾節(jié)點(diǎn)指針、以及鏈表內(nèi)的節(jié)點(diǎn)數(shù)量。

2.3 緩沖頁(yè)哈希表

第二個(gè)問(wèn)題又來(lái)了,當(dāng)我們要使用某個(gè)頁(yè)的時(shí)候,怎么知道它有沒(méi)有被加載到Buffer Pool呢?難道又要再遍歷一次所有已使用的緩沖頁(yè)嗎?未免也太笨拙了。

在同一個(gè)表空間里,每個(gè)頁(yè)都有唯一的一個(gè)頁(yè)號(hào),所以要定位一個(gè)頁(yè),只需要知道表空間ID+頁(yè)號(hào)就可以了。也就是說(shuō),我們完全可以建立一個(gè)哈希表,哈希表的Key就是表空間ID+頁(yè)號(hào)的組合,Value就是緩沖頁(yè)。這樣就可以快速判斷某個(gè)頁(yè)是否已經(jīng)加載到Buffer Pool了。

2.4 Flush鏈表

在執(zhí)行增刪改操作時(shí),如果InnoDB每次都把受影響的頁(yè)同步到磁盤(pán),那么必然會(huì)導(dǎo)致大量的磁盤(pán)隨機(jī)IO寫(xiě)操作,這個(gè)效率是很低的。為了提升性能,InnoDB會(huì)先在內(nèi)存里修改這些受影響的頁(yè)面,這些被修改過(guò)的頁(yè)面稱(chēng)作「臟頁(yè)」(Dirty Page),然后由一個(gè)額外的線程負(fù)責(zé)將這些臟頁(yè)刷新到磁盤(pán)。

內(nèi)存斷電數(shù)據(jù)就丟失了,那些沒(méi)來(lái)得及刷盤(pán)的臟頁(yè)豈不是數(shù)據(jù)就丟失了?不用擔(dān)心,后面聊的redo log會(huì)幫我們保證數(shù)據(jù)一致性的,這里先跳過(guò)。

第三個(gè)問(wèn)題又來(lái)了,InnoDB怎么知道哪些頁(yè)是臟頁(yè)呢?再遍歷一次Buffer Pool嗎?太笨拙了,為了解決這個(gè)問(wèn)題,InnoDB又引入了第二條鏈表:flush鏈表。

flush鏈表和free鏈表極其相似,也有一個(gè)鏈表基節(jié)點(diǎn),當(dāng)我們修改了緩沖頁(yè)里的數(shù)據(jù),InnoDB就會(huì)把該緩沖頁(yè)對(duì)應(yīng)的控制塊加入到flush鏈表,等待后續(xù)的刷盤(pán)。

2.5 LRU鏈表

那些已經(jīng)被使用的緩沖頁(yè),會(huì)從Free鏈表中移除,然后加入到一個(gè)叫作“LRU”的鏈表中。LRU是Least Recently Used的縮寫(xiě),譯為“最近最少使用”。為啥會(huì)需要LRU鏈表呢?說(shuō)白了,相較于磁盤(pán)上海量的數(shù)據(jù),Buffer Pool那點(diǎn)內(nèi)存實(shí)在是杯水車(chē)薪,當(dāng)Buffer Pool中的內(nèi)存不夠時(shí),就不得不釋放掉一些頁(yè)面,來(lái)緩存新的頁(yè)面。

Buffer Pool的本質(zhì)是為了減少磁盤(pán)IO的訪問(wèn),提高緩存命中率,正是因?yàn)樗〔棚@得極其珍貴,InnoDB更應(yīng)該要用好它。如果是你,你會(huì)在Buffer Pool里放訪問(wèn)頻率高的頁(yè)面,還是訪問(wèn)頻率低的頁(yè)面呢?

最簡(jiǎn)單的LRU鏈表,每當(dāng)我們要訪問(wèn)一個(gè)頁(yè)面時(shí),就把它移動(dòng)到LRU鏈表的表頭,那么鏈尾的頁(yè)面自然就是最近最少使用的了,當(dāng)Free鏈表沒(méi)有空閑的緩沖頁(yè)時(shí),直接把LRU鏈表的鏈尾頁(yè)面釋放掉即可。看似沒(méi)什么問(wèn)題,但是某些場(chǎng)景下,LRU鏈表會(huì)被破壞:

1.全表掃描:全表掃描需要加載聚簇索引B+樹(shù)的所有葉子節(jié)點(diǎn),當(dāng)表中數(shù)據(jù)量較大時(shí),可能一次全表掃描就會(huì)把之前訪問(wèn)頻率很高的緩沖頁(yè)全部從LRU鏈表中擠出,下次再訪問(wèn)這些頁(yè)面時(shí),又得從磁盤(pán)上重新加載一遍了。

2.預(yù)讀:InnoDB內(nèi)置了一個(gè)貼心的預(yù)讀功能,它會(huì)在執(zhí)行當(dāng)前讀請(qǐng)求時(shí),判斷是否還會(huì)訪問(wèn)其它頁(yè)面,然后異步的把這些頁(yè)面提前加載到Buffer Pool,從而加速讀操作。預(yù)讀細(xì)分為兩種:

  • 2.1線性預(yù)讀:系統(tǒng)變量innodb_read_ahead_threshold代表觸發(fā)線性預(yù)讀的閾值,如果順序的訪問(wèn)某個(gè)區(qū)的頁(yè)面數(shù)量超過(guò)該值,InnoDB就會(huì)異步的將下一個(gè)區(qū)的所有頁(yè)面加載到Buffer Pool,默認(rèn)值56。
  • 2.2隨機(jī)預(yù)讀:系統(tǒng)變量innodb_random_read_ahead代表觸發(fā)隨機(jī)預(yù)讀的閾值,如果某個(gè)區(qū)的13個(gè)連續(xù)的頁(yè)面被加載到Buffer Pool,InnoDB就會(huì)異步的將本區(qū)其它頁(yè)面全部加載到Buffer Pool,該功能默認(rèn)關(guān)閉。

綜上所述,全表掃描和預(yù)讀可能會(huì)破壞LRU鏈表,本質(zhì)上就是將大量可能短期不會(huì)被訪問(wèn)到的頁(yè)面加入到LRU鏈表,反而導(dǎo)致那些訪問(wèn)頻率很高的頁(yè)面被擠掉了,導(dǎo)致Buffer Pool的命中率降低。

為了解決這個(gè)問(wèn)題,InnoDB對(duì)LRU鏈表進(jìn)行了優(yōu)化,將LRU鏈表按照一定的比例分成兩部分:存儲(chǔ)訪問(wèn)頻率很高的Young區(qū)、存儲(chǔ)訪問(wèn)頻率較低的Old區(qū)。系統(tǒng)變量innodb_old_blocks_pct控制了Old區(qū)所占的比例,默認(rèn)值是37。也就是說(shuō),整個(gè)LRU鏈表的前約5/8部分用來(lái)存儲(chǔ)訪問(wèn)頻率很高的緩沖頁(yè),后約3/8部分用來(lái)存儲(chǔ)訪問(wèn)頻率較低的緩沖頁(yè)。

將LRU鏈表劃分為兩截后,InnoDB是這樣來(lái)維護(hù)LRU鏈表的:首次加載的頁(yè)面不會(huì)直接放到LRU鏈表的表頭,而是Old區(qū)的頭部,如果該頁(yè)面后續(xù)沒(méi)有繼續(xù)訪問(wèn),會(huì)慢慢被釋放掉,而不影響Young區(qū)的頁(yè)面。如果后續(xù)再次訪問(wèn)了該頁(yè)面,判斷距離上次訪問(wèn)的時(shí)間,只有兩次訪問(wèn)的時(shí)間間隔超過(guò)了閾值,才會(huì)把它移動(dòng)到Y(jié)oung區(qū)頭部。

時(shí)間間隔的閾值通過(guò)系統(tǒng)變量innodb_old_blocks_time配置,默認(rèn)是1000ms。

LRU鏈表經(jīng)過(guò)這么一番優(yōu)化后,我們看看是如何解決上面兩個(gè)場(chǎng)景的:

  • 全表掃描:全表掃描的頁(yè)面首次加載只會(huì)放在Old區(qū)頭部,雖然馬上又會(huì)訪問(wèn)同一個(gè)頁(yè)面,但是時(shí)間間隔很短,因此不會(huì)移動(dòng)到Y(jié)oung區(qū)。(每一條記錄都要訪問(wèn)一次頁(yè)面)
  • 預(yù)讀:預(yù)讀首次加載的頁(yè)面只會(huì)放在Old區(qū)頭部,只要后續(xù)不再繼續(xù)訪問(wèn),就會(huì)慢慢被釋放掉。

對(duì)于Young區(qū)的緩沖頁(yè),如果每訪問(wèn)一次都要把它移動(dòng)到LRU鏈表的表頭,這個(gè)操作未免也太頻繁了,因?yàn)閅oung區(qū)本來(lái)就是訪問(wèn)頻率很高的頁(yè)面,大家互相換來(lái)?yè)Q去意義不大。所以InnoDB再進(jìn)一步優(yōu)化,如果訪問(wèn)的緩沖頁(yè)在Young區(qū)的前1/4處,是不需要移動(dòng)到表頭的,只有訪問(wèn)的緩沖頁(yè)在Young區(qū)的后3/4處才會(huì)把它移動(dòng)到表頭,這大大降低了鏈表節(jié)點(diǎn)移動(dòng)的頻率。

2.6 多個(gè)實(shí)例

現(xiàn)在我們知道,Buffer Pool在物理上雖然是一塊連續(xù)的內(nèi)存空間,但是邏輯上它由多條鏈表組成。在維護(hù)這些鏈表時(shí),都需要加鎖來(lái)保證同步,在高并發(fā)場(chǎng)景下,這會(huì)帶來(lái)一些性能上的影響。為了解決這個(gè)問(wèn)題,InnoDB支持多個(gè)Buffer Pool實(shí)例,每個(gè)實(shí)例都是獨(dú)立的,會(huì)維護(hù)自己的各種鏈表,多線程并發(fā)訪問(wèn)時(shí)不會(huì)有影響,從而提高并發(fā)處理能力。

查看Buffer Pool實(shí)例個(gè)數(shù)的命令,默認(rèn)是1個(gè)。

mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_instances';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_buffer_pool_instances | 1     |
+------------------------------+-------+

支持在配置文件中進(jìn)行配置:

[server]
innodb_buffer_pool_size=2147483648
innodb_buffer_pool_instances=2

在MySQL5.7.5之前,InnoDB是不支持運(yùn)行時(shí)動(dòng)態(tài)調(diào)整Buffer Pool大小的,主要是因?yàn)槊看握{(diào)整大小,都需要向操作系統(tǒng)重新申請(qǐng)一個(gè)Buffer Pool,然后將數(shù)據(jù)拷貝一次,這個(gè)開(kāi)銷(xiāo)太大了。在之后的版本中,InnoDB引入了chunk的概念來(lái)支持運(yùn)行時(shí)修改Buffer Pool大小。一個(gè)Buffer Pool實(shí)例由若干個(gè)chunk組成,里面包含了若干個(gè)控制塊和緩沖頁(yè)。在調(diào)整Buffer Pool大小時(shí),InnoDB以chunk為單位來(lái)申請(qǐng)內(nèi)存空間和數(shù)據(jù)的拷貝。

chunk的大小由系統(tǒng)變量innodb_buffer_pool_chunk_size控制,默認(rèn)是128MB,chunk本身的大小不支持運(yùn)行時(shí)修改。

mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_chunk_size';
+-------------------------------+-----------+
| Variable_name                 | Value     |
+-------------------------------+-----------+
| innodb_buffer_pool_chunk_size | 134217728 |
+-------------------------------+-----------+

innodb_buffer_pool_size必須是innodb_buffer_pool_chunk_size*innodb_buffer_pool_instances的整數(shù)倍大小,目的是保證沒(méi)個(gè)Buffer Pool實(shí)例的chunk數(shù)量一致。

2.7 Buffer Pool狀態(tài)信息

說(shuō)了這么多,耳聽(tīng)為虛,眼見(jiàn)為實(shí)。如何查看MySQL運(yùn)行時(shí)的Buffer Pool相關(guān)的狀態(tài)信息呢?命令是SHOW ENGINE INNODB STATUS,輸出的是InnoDB引擎的狀態(tài)信息,其中就包含Buffer Pool的狀態(tài)信息,如下:

----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 137428992
Dictionary memory allocated 268616
Buffer pool size   8191
Free buffers       7238
Database pages     953
Old database pages 371
Modified db pages  0
Pending reads      0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 919, created 34, written 36
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
Buffer pool hit rate 740 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 959, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

  • Total large memory allocated:Buffer Pool向操作系統(tǒng)申請(qǐng)的總內(nèi)存大小,包括控制塊大小。
  • Dictionary memory allocated:給數(shù)據(jù)字典分配的內(nèi)存大小,不包含在Buffer Pool總內(nèi)存大小中。
  • Buffer pool size:Buffer Pool可以容納多少緩沖頁(yè)。
  • Free buffers:Free鏈表的頁(yè)面數(shù)。
  • Database pages:LRU鏈表的頁(yè)面數(shù)。
  • Old database pages:LRU鏈表Old區(qū)域的頁(yè)面數(shù)。
  • Modified db pages:臟頁(yè)數(shù)量,即Flush鏈表的頁(yè)面數(shù)。
  • Pending reads:等待從磁盤(pán)加載到Buffer Pool的頁(yè)面數(shù)。
  • Pending writes.LRU:等待從LRU鏈表中刷新到磁盤(pán)的頁(yè)面數(shù)。
  • Pending writes.flush list:等待從Flush鏈表中刷新到磁盤(pán)的頁(yè)面數(shù)。
  • Pending writes.single page:等待以單個(gè)頁(yè)面的形式刷新到磁盤(pán)的頁(yè)面數(shù)。
  • Pages made young:LRU鏈表曾經(jīng)從Old區(qū)移動(dòng)到Y(jié)oung區(qū)的節(jié)點(diǎn)數(shù)。
  • Pages made not young:再次訪問(wèn)Old區(qū)的節(jié)點(diǎn)因?yàn)闀r(shí)間問(wèn)題不能移動(dòng)到Y(jié)oung區(qū)的節(jié)點(diǎn)數(shù)。
  • youngs/s:每秒從Old移動(dòng)到Y(jié)oung區(qū)的節(jié)點(diǎn)數(shù)。
  • non-youngs/s:每秒由于時(shí)間限制不能從Old移動(dòng)到Y(jié)oung區(qū)的節(jié)點(diǎn)數(shù)。
  • Pages read/created/written:讀取/創(chuàng)建/寫(xiě)入了多少頁(yè)面,下一行是對(duì)應(yīng)的速率。
  • Buffer pool hit rate:過(guò)去平均每訪問(wèn)一千次頁(yè)面,有多少次頁(yè)面已經(jīng)被緩存到Buffer Pool。
  • young-making rate:過(guò)去平均每訪問(wèn)一千次頁(yè)面,有多少次使頁(yè)面移動(dòng)到Y(jié)oung區(qū)頭部。
  • not young-making rate:過(guò)去平均每訪問(wèn)一千次頁(yè)面,有多少次沒(méi)有使頁(yè)面移動(dòng)到Y(jié)oung區(qū)頭部。
  • LRU len:LRU鏈表的節(jié)點(diǎn)數(shù)。
  • I/O sum:最近50秒,讀取磁盤(pán)的總頁(yè)數(shù)。
  • I/O cur:現(xiàn)在正在讀取磁盤(pán)頁(yè)的數(shù)量。
  • I/O unzip sum:最近50秒解壓的頁(yè)面數(shù)。
  • I/O unzip cur:正在解壓的頁(yè)面數(shù)。

3. 總結(jié)

磁盤(pán)速度太慢了,如果每次讀取頁(yè)面都從磁盤(pán)加載,會(huì)導(dǎo)致大量的磁盤(pán)IO隨機(jī)讀,MySQL的性能勢(shì)必會(huì)受到嚴(yán)重影響。為了解決這個(gè)問(wèn)題,InnoDB引入了Buffer Pool,它會(huì)在MySQL服務(wù)器啟動(dòng)時(shí)申請(qǐng)一塊連續(xù)的內(nèi)存空間,用來(lái)緩存對(duì)應(yīng)的磁盤(pán)里的頁(yè)結(jié)構(gòu)。每個(gè)緩沖頁(yè)都有一個(gè)與之關(guān)聯(lián)的控制塊,InnoDB為了不同的目的,將這些控制塊串聯(lián)成多條雙向鏈表,例如:Free鏈表、LRU鏈表、Flush鏈表等等。為了提高Buffer Pool的命中率,防止一些特殊的操作破壞LRU鏈表,InnoDB將LRU鏈表按照一定的比例劃分成兩截,分別是存放訪問(wèn)頻率很高的頁(yè)的Young區(qū),和訪問(wèn)頻率較低的頁(yè)的Old區(qū)。Buffer Pool邏輯上由這些鏈表組成,維護(hù)這些鏈表都需要加鎖保證同步,高并發(fā)下會(huì)影響性能,所以InnoDB支持配置多個(gè)Buffer Pool實(shí)例。為了在運(yùn)行時(shí)支持調(diào)整Buffer Pool的大小,InnoDB又引入了chunk的概念,最后通過(guò)命令我們可以查看Buffer Pool的狀態(tài)信息。

到此這篇關(guān)于MySql InnoDB存儲(chǔ)引擎之Buffer Pool運(yùn)行原理講解的文章就介紹到這了,更多相關(guān)MySql InnoDB Buffer Pool內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL curdate()函數(shù)的實(shí)例詳解

    MySQL curdate()函數(shù)的實(shí)例詳解

    這篇文章主要介紹了MySQL curdate()函數(shù)的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家理解應(yīng)用MysqL curdate()的使用方法,需要的朋友可以參考下
    2017-09-09
  • MySQL中用戶(hù)授權(quán)以及刪除授權(quán)的方法

    MySQL中用戶(hù)授權(quán)以及刪除授權(quán)的方法

    這篇文章主要介紹了MySQL中用戶(hù)授權(quán)以及刪除授權(quán)的方法的相關(guān)資料,需要的朋友可以參考下
    2015-12-12
  • Mysql主從數(shù)據(jù)庫(kù)(Master/Slave)同步配置與常見(jiàn)錯(cuò)誤

    Mysql主從數(shù)據(jù)庫(kù)(Master/Slave)同步配置與常見(jiàn)錯(cuò)誤

    今天小編就為大家分享一篇關(guān)于Mysql主從數(shù)據(jù)庫(kù)(Master/Slave)同步配置與常見(jiàn)錯(cuò)誤,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • MySQL 不等于的三種使用及區(qū)別

    MySQL 不等于的三種使用及區(qū)別

    MySQL中常用到判斷符號(hào),而不等于是比較常用的符號(hào),不等于主要是三種,本文主要介紹了三種的使用及區(qū)別,感興趣的同學(xué)可以了解一下
    2021-06-06
  • MYSQL METADATA LOCK(MDL LOCK)MDL鎖問(wèn)題分析

    MYSQL METADATA LOCK(MDL LOCK)MDL鎖問(wèn)題分析

    這篇文章主要介紹了MYSQL METADATA LOCK(MDL LOCK)MDL鎖問(wèn)題分析,并通過(guò)實(shí)例給大家例句的問(wèn)題處理辦法,需要的朋友參考學(xué)習(xí)下。
    2017-12-12
  • MySQL中查詢(xún)json格式的字段實(shí)例詳解

    MySQL中查詢(xún)json格式的字段實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于MySQL中查詢(xún)json格式字段的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 一文搞懂MySQL XA如何實(shí)現(xiàn)分布式事務(wù)

    一文搞懂MySQL XA如何實(shí)現(xiàn)分布式事務(wù)

    MySQL如何實(shí)現(xiàn)多個(gè)MySQL數(shù)據(jù)庫(kù)更新的一致性呢?那就是MySQL XA,本文就來(lái)介紹一下MySQL XA如何實(shí)現(xiàn)分布式事務(wù),具有一定的參考價(jià)值,感興趣的可以了解一下
    2021-11-11
  • MySQL主從復(fù)制斷開(kāi)的常用修復(fù)方法

    MySQL主從復(fù)制斷開(kāi)的常用修復(fù)方法

    這篇文章主要介紹了MySQL主從復(fù)制斷開(kāi)的常用修復(fù)方法,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-04-04
  • SQL查詢(xún)語(yǔ)句執(zhí)行的過(guò)程

    SQL查詢(xún)語(yǔ)句執(zhí)行的過(guò)程

    這篇文章主要介紹了SQL查詢(xún)語(yǔ)句執(zhí)行的過(guò)程,文章圍繞主題展開(kāi)SQL查詢(xún)語(yǔ)句的相關(guān)資料,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • 詳解MySQL中的事務(wù)與ACID特性

    詳解MySQL中的事務(wù)與ACID特性

    這篇文章主要為大家介紹了Mysql?中的事務(wù),包括事務(wù)的基本概念和?ACID?特性、事務(wù)的隔離級(jí)別和具體實(shí)現(xiàn)方法等,并提供相應(yīng)的代碼示例,希望對(duì)大家有所幫助
    2023-05-05

最新評(píng)論