最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

16 簡(jiǎn)單的LRU鏈表在Buffer Pool實(shí)際運(yùn)行中,可能導(dǎo)致哪些問(wèn)題?

2023-06-17 14:30 作者:儒猿課堂  | 我要投稿

簡(jiǎn)單的LRU鏈表在Buffer Pool實(shí)際運(yùn)行中,可能導(dǎo)致哪些問(wèn)題?


1、簡(jiǎn)單回顧一下


之前我們講解了Buffer Pool在使用過(guò)程中如果緩存頁(yè)都使用了,沒(méi)有空閑的緩存頁(yè)時(shí),可以去LRU鏈表中的尾部找一個(gè)最近最少使用的緩存頁(yè),把他的數(shù)據(jù)刷入磁盤,騰出來(lái)一個(gè)空閑緩存頁(yè),然后加載需要的新的磁盤數(shù)據(jù)頁(yè)到空閑緩存頁(yè)里去。


而LRU鏈表的機(jī)制也很簡(jiǎn)單,只要是剛從磁盤上加載數(shù)據(jù)到緩存頁(yè)里去,這個(gè)緩存頁(yè)就放入LRU鏈表的頭部,后續(xù)如果對(duì)任何一個(gè)緩存頁(yè)訪問(wèn)了,也把緩存頁(yè)從LRU鏈表中移動(dòng)到頭部去。


這樣在LRU鏈表的尾部,一定是最近最少被訪問(wèn)的那個(gè)緩存頁(yè)。


2、預(yù)讀帶來(lái)的一個(gè)巨大問(wèn)題


但是這樣的一個(gè)LRU機(jī)制在實(shí)際運(yùn)行過(guò)程中,是會(huì)存在巨大的隱患的。


首先會(huì)帶來(lái)隱患的就是MySQL的預(yù)讀機(jī)制,這個(gè)所謂預(yù)讀機(jī)制,說(shuō)的就是當(dāng)你從磁盤上加載一個(gè)數(shù)據(jù)頁(yè)的時(shí)候,他可能會(huì)連帶著把這個(gè)數(shù)據(jù)頁(yè)相鄰的其他數(shù)據(jù)頁(yè),也加載到緩存里去!


舉個(gè)例子,假設(shè)現(xiàn)在有兩個(gè)空閑緩存頁(yè),然后在加載一個(gè)數(shù)據(jù)頁(yè)的時(shí)候,連帶著把他的一個(gè)相鄰的數(shù)據(jù)頁(yè)也加載到緩存里去了,正好每個(gè)數(shù)據(jù)頁(yè)放入一個(gè)空閑緩存頁(yè)!


但是接下來(lái)呢,實(shí)際上只有一個(gè)緩存頁(yè)是被訪問(wèn)了,另外一個(gè)通過(guò)預(yù)讀機(jī)制加載的緩存頁(yè),其實(shí)并沒(méi)有人訪問(wèn),此時(shí)這兩個(gè)緩存頁(yè)可都在LRU鏈表的前面,如下圖。

? ? ? ? ? ?

? ? ? ? ? ? ?

我們可以看到,這個(gè)圖里很清晰的表明了,前兩個(gè)緩存頁(yè)都是剛加載進(jìn)來(lái)的,但是此時(shí)第二個(gè)緩存頁(yè)是通過(guò)預(yù)讀機(jī)制捎帶著加載進(jìn)來(lái)的,他也放到了鏈表的前面,但是他實(shí)際沒(méi)人訪問(wèn)他。


除了第二個(gè)緩存頁(yè)之外,第一個(gè)緩存頁(yè),以及尾巴上兩個(gè)緩存頁(yè),都是一直有人訪問(wèn)的那種緩存頁(yè),只不過(guò)上圖代表的是剛剛把頭部?jī)蓚€(gè)緩存頁(yè)加載進(jìn)來(lái)的時(shí)候的一個(gè)LRU鏈表當(dāng)時(shí)的情況。


這個(gè)時(shí)候,假如沒(méi)有空閑緩存頁(yè)了,那么此時(shí)要加載新的數(shù)據(jù)頁(yè)了,是不是就要從LRU鏈表的尾部把所謂的“最近最少使用的一個(gè)緩存頁(yè)”給拿出來(lái),刷入磁盤,然后騰出來(lái)一個(gè)空閑緩存頁(yè)了?


這個(gè)時(shí)候,如果你把上圖中LRU尾部的那個(gè)緩存頁(yè)刷入磁盤然后清空,你覺(jué)得合理嗎?他可是之前一直頻繁被人訪問(wèn)的啊!只不過(guò)在這一個(gè)瞬間,被新加載進(jìn)來(lái)的兩個(gè)緩存頁(yè)給占據(jù)了LRU鏈表前面的位置,尤其是第二個(gè)緩存頁(yè),居然還是通過(guò)預(yù)讀機(jī)制加載進(jìn)來(lái)的,根本就不會(huì)有人訪問(wèn)!


那么這個(gè)時(shí)候,你要是把LRU鏈表尾部的緩存頁(yè)給刷入磁盤,這是絕對(duì)不合理的,最合理的反而是把上圖中LRU鏈表的第二個(gè)通過(guò)預(yù)讀機(jī)制加載進(jìn)來(lái)的緩存頁(yè)給刷入磁盤和清空,畢竟他幾乎是沒(méi)什么人會(huì)訪問(wèn)的!


3、哪些情況下會(huì)觸發(fā)MySQL的預(yù)讀機(jī)制?


現(xiàn)在我們已經(jīng)理解了預(yù)讀機(jī)制一下子把相鄰的數(shù)據(jù)頁(yè)加載進(jìn)緩存,放入LRU鏈表前面的隱患了,預(yù)讀機(jī)制加載進(jìn)來(lái)的緩存頁(yè)可能根本不會(huì)有人訪問(wèn),結(jié)果他卻放在了LRU鏈表的前面,此時(shí)可能會(huì)把LRU尾部的那些被頻繁訪問(wèn)的緩存頁(yè)刷入磁盤中!


所以我們來(lái)看看,到底哪些情況下會(huì)觸發(fā)MySQL的預(yù)讀機(jī)制呢?


(1)有一個(gè)參數(shù)是innodb_read_ahead_threshold,他的默認(rèn)值是56,意思就是如果順序的訪問(wèn)了一個(gè)區(qū)里的多個(gè)數(shù)據(jù)頁(yè),訪問(wèn)的數(shù)據(jù)頁(yè)的數(shù)量超過(guò)了這個(gè)閾值,此時(shí)就會(huì)觸發(fā)預(yù)讀機(jī)制,把下一個(gè)相鄰區(qū)中的所有數(shù)據(jù)頁(yè)都加載到緩存里去


(2)如果Buffer Pool里緩存了一個(gè)區(qū)里的13個(gè)連續(xù)的數(shù)據(jù)頁(yè),而且這些數(shù)據(jù)頁(yè)都是比較頻繁會(huì)被訪問(wèn)的,此時(shí)就會(huì)直接觸發(fā)預(yù)讀機(jī)制,把這個(gè)區(qū)里的其他的數(shù)據(jù)頁(yè)都加載到緩存里去


這個(gè)機(jī)制是通過(guò)參數(shù)innodb_random_read_ahead來(lái)控制的,他默認(rèn)是OFF,也就是這個(gè)規(guī)則是關(guān)閉的


所以默認(rèn)情況下,主要是第一個(gè)規(guī)則可能會(huì)觸發(fā)預(yù)讀機(jī)制,一下子把很多相鄰區(qū)里的數(shù)據(jù)頁(yè)加載到緩存里去,這些緩存頁(yè)如果一下子都放在LRU鏈表的前面,而且他們其實(shí)并沒(méi)什么人會(huì)訪問(wèn)的話,那就會(huì)如上圖,導(dǎo)致本來(lái)就在緩存里的一些頻繁被訪問(wèn)的緩存頁(yè)在LRU鏈表的尾部。


這樣的話,一旦要把一些緩存頁(yè)淘汰掉,刷入磁盤,騰出來(lái)空閑緩存頁(yè),就會(huì)如上所述,把LRU鏈表尾部一些頻繁被訪問(wèn)的緩存頁(yè)給刷入磁盤和清空掉了!這是完全不合理的,并不應(yīng)該這樣!


4、另外一種可能導(dǎo)致頻繁被訪問(wèn)的緩存頁(yè)被淘汰的場(chǎng)景


接著我們講另外一種可能導(dǎo)致頻繁被訪問(wèn)的緩存頁(yè)被淘汰的場(chǎng)景,那就是全表掃描


這個(gè)所謂的全表掃描,意思就是類似如下的SQL語(yǔ)句:SELECT * FROM USERS


此時(shí)他沒(méi)加任何一個(gè)where條件,會(huì)導(dǎo)致他直接一下子把這個(gè)表里所有的數(shù)據(jù)頁(yè),都從磁盤加載到Buffer Pool里去。


這個(gè)時(shí)候他可能會(huì)一下子就把這個(gè)表的所有數(shù)據(jù)頁(yè)都一一裝入各個(gè)緩存頁(yè)里去!此時(shí)可能LRU鏈表中排在前面的一大串緩存頁(yè),都是全表掃描加載進(jìn)來(lái)的緩存頁(yè)!那么如果這次全表掃描過(guò)后,后續(xù)幾乎沒(méi)用到這個(gè)表里的數(shù)據(jù)呢?


此時(shí)LRU鏈表的尾部,可能全部都是之前一直被頻繁訪問(wèn)的那些緩存頁(yè)!


然后當(dāng)你要淘汰掉一些緩存頁(yè)騰出空間的時(shí)候,就會(huì)把LRU鏈表尾部一直被頻繁訪問(wèn)的緩存頁(yè)給淘汰掉了,而留下了之前全表掃描加載進(jìn)來(lái)的大量的不經(jīng)常訪問(wèn)的緩存頁(yè)!


5、總結(jié)


所以我們來(lái)對(duì)今天講到的內(nèi)容做一點(diǎn)小小的總結(jié),如果你使用簡(jiǎn)單的LRU鏈表的機(jī)制,其實(shí)是漏洞百出的,因?yàn)楹芸赡茴A(yù)讀機(jī)制,或者全表掃描的機(jī)制,都會(huì)一下子把大量未來(lái)可能不怎么訪問(wèn)的數(shù)據(jù)頁(yè)加載到緩存頁(yè)里去,然后LRU鏈表的前面全部是這些未來(lái)可能不怎么會(huì)被訪問(wèn)的緩存頁(yè)!


而真正之前一直頻繁被訪問(wèn)的緩存頁(yè)可能此時(shí)都在LRU鏈表的尾部了!


如果此時(shí)此刻,需要把一些緩存頁(yè)刷入磁盤,騰出空間來(lái)加載新的數(shù)據(jù)頁(yè),那么此時(shí)就只能把LRU鏈表尾部那些一直頻繁被訪問(wèn)的緩存頁(yè)給刷入磁盤了!


最后我們?cè)倏匆幌孪旅娴膱D示,想必大家是很好理解的。

? ? ? ? ? ?

? ? ? ? ? ? ?

6、今日思考題


今天希望大家思考一下:

  • 為什么MySQL要設(shè)計(jì)預(yù)讀這個(gè)機(jī)制?

  • 他加載一個(gè)數(shù)據(jù)頁(yè)到緩存里去的時(shí)候,為什么要把一些相鄰的數(shù)據(jù)頁(yè)也加載到緩存里去呢?這么做的意義在哪里?

  • 是為了應(yīng)對(duì)什么樣的一個(gè)場(chǎng)景?


希望大家積極思考,在評(píng)論區(qū)給出自己的答案!

End

專欄版權(quán)歸公眾號(hào)儒猿技術(shù)窩所有

未經(jīng)許可不得傳播,如有侵權(quán)將追究法律責(zé)任

16 簡(jiǎn)單的LRU鏈表在Buffer Pool實(shí)際運(yùn)行中,可能導(dǎo)致哪些問(wèn)題?的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
苏尼特右旗| 巴林左旗| 博爱县| 高淳县| 汾西县| 永川市| 边坝县| 昭通市| 博爱县| 隆尧县| 大渡口区| 翁源县| 望城县| 忻州市| 太仆寺旗| 县级市| 长治县| 桐庐县| 萍乡市| 邻水| 庆安县| 建湖县| 宁德市| 吴旗县| 河间市| 虞城县| 延长县| 沐川县| 郑州市| 奎屯市| 和硕县| 杨浦区| 荃湾区| 喀喇| 太仆寺旗| 那坡县| 巨鹿县| 宁陕县| 孝义市| 河西区| 罗平县|