MySQL:當(dāng)你CRUD時(shí)BufferPool中發(fā)生了什么双仍?十張圖就能說清楚

一、前言

你知道的桌吃,MySQL對(duì)數(shù)據(jù)的增刪改查都是內(nèi)存中完成的朱沃,這塊內(nèi)存就是Buffer Pool。

你可以像下面這樣查看下你的MySQL的Buffer的Buffer Pool的默認(rèn)大小

image

上圖中的0.125單位為GB茅诱,轉(zhuǎn)換成MB就是 1024* 1/8 = 128MB

總結(jié)來說逗物,就是MySQL啟動(dòng)后就會(huì)為我們初始化好這塊Buffer Pool。如下圖:

image

你可以看著上圖瑟俭,然后讀下面這段話:

MySQL以數(shù)據(jù)頁為單位翎卓,從磁盤中讀取數(shù)據(jù)。數(shù)據(jù)頁被讀取到內(nèi)存中摆寄,所謂的內(nèi)存其實(shí)就是Buffer Pool失暴。

Buffer Pool中維護(hù)的數(shù)據(jù)結(jié)構(gòu)是緩存頁,而且每個(gè)緩存頁都有它對(duì)應(yīng)的描述信息微饥。

由于MySQL剛啟動(dòng)逗扒,還沒有從磁盤中讀取任何數(shù)據(jù)頁到內(nèi)存(Buffer Pool)中,那此時(shí)Buffer Pool中所有的緩存頁其實(shí)都是空的欠橘。

除了緩存頁之外矩肩,你還能看到Buffer Pool中存在三個(gè)雙向鏈表。分別是FreeList肃续、LRUList以及FlushList黍檩。這三個(gè)雙向鏈表中維護(hù)著緩存頁的描述信息。

二始锚、好刽酱,假設(shè)你讀取出來了1個(gè)數(shù)據(jù)頁

當(dāng)你通過select讀取出一個(gè)數(shù)據(jù)頁之后,是需要將這個(gè)數(shù)據(jù)頁加載進(jìn)Buffer Pool中的緩存頁中的瞧捌。

那問題來了棵里,MySQL怎么知道該將你讀取出來的數(shù)據(jù)頁存放在那個(gè)緩存頁中呢?相信你看了上圖應(yīng)該也能想到答案了。FreeList這個(gè)雙向鏈表不是存放了空閑的緩存頁的描述信息嗎衍慎?那從FreeList中取出一個(gè)空間緩存頁的描述信息不就好了?于是得到了下面這張圖:

image

啰嗦一點(diǎn):對(duì)這張圖稍微做一下解讀:

InnoDB會(huì)將你讀取出來的數(shù)據(jù)頁加載進(jìn)Buffer Pool中的緩存頁中皮钠,然后緩存頁的描述信息也會(huì)被維護(hù)進(jìn)LRU鏈表中稳捆。鏈表做了冷熱數(shù)據(jù)分離優(yōu)化,5/8的區(qū)域是熱數(shù)據(jù)區(qū)域麦轰,3/8的區(qū)域算是冷數(shù)據(jù)區(qū)域乔夯。(本質(zhì)上它們都是雙向鏈表),而你新讀取的數(shù)據(jù)頁會(huì)被放在冷數(shù)據(jù)區(qū)的靠前的位置上款侵。

如果你將該數(shù)據(jù)頁讀取出來加載進(jìn)緩存頁中后末荐,間隔沒到1s,就使用該緩存頁新锈。那么InnoDB是不會(huì)將這個(gè)描述信息移動(dòng)到5/8的熱數(shù)據(jù)區(qū)域的甲脏。

但是當(dāng)超過1s后,你又去讀這個(gè)數(shù)據(jù)頁妹笆。那這個(gè)數(shù)據(jù)頁的描述信息就會(huì)被放到熱數(shù)據(jù)區(qū)域块请。如下圖:

image

三、假設(shè)你一次性讀取出來了好多數(shù)據(jù)頁

白日夢在第 6 篇文章中跟大家分享過拳缠,MySQL是存在預(yù)讀機(jī)制的墩新,感興趣可關(guān)注公眾號(hào)閱讀。

假設(shè)觸發(fā)了MySQL的預(yù)讀機(jī)制窟坐。一次性從磁盤中讀取來N多個(gè)緩存頁海渊。會(huì)得到下面這張圖:

image

因?yàn)榘l(fā)生了預(yù)讀,所以你的一次磁盤IO讀出了大量的數(shù)據(jù)頁哲鸳,但是這些數(shù)據(jù)頁中很可能是有一些是你根本不需要的臣疑,僅僅是預(yù)讀把它們級(jí)聯(lián)查出來了。這時(shí)按老規(guī)矩徙菠,從FreeList中找到空閑的緩存頁信息朝捆,然后將其從FreeList中移除。根據(jù)找到的空閑緩存頁的描述信息懒豹,將從磁盤中讀取出來的數(shù)據(jù)頁加載進(jìn)去芙盘。相應(yīng)的該緩存頁的描述信息也會(huì)被維護(hù)進(jìn)LRU鏈表的冷數(shù)據(jù)區(qū)域。

這時(shí)你就會(huì)發(fā)現(xiàn)這種冷熱數(shù)據(jù)分離的機(jī)制多么妙脸秽!即使發(fā)生了預(yù)讀又怎么樣儒老?根本沒有機(jī)會(huì)將熱數(shù)據(jù)區(qū)的描述信息1擠下去。當(dāng)內(nèi)存不夠用了需要將部分緩存頁刷新到磁盤中時(shí)记餐,那就從冷數(shù)據(jù)區(qū)域開始刷新好了驮樊,反正他們本來就不經(jīng)常被使用。

同樣的,當(dāng)你超過1s后又訪問了冷數(shù)據(jù)區(qū)的緩存頁囚衔,比如訪問了緩存頁66和數(shù)據(jù)頁67挖腰,該緩存頁對(duì)應(yīng)的描述信息是會(huì)被提升到熱數(shù)據(jù)區(qū),于是有了下面這張圖:

image

那练湿,如果你訪問上圖中的數(shù)據(jù)頁67猴仑,它會(huì)移動(dòng)到描述信息66所在節(jié)點(diǎn)的前面去嗎?

其實(shí)MySQL的LRU鏈表做了優(yōu)化肥哎,數(shù)據(jù)67是不會(huì)往前跑的辽俗。

四、假設(shè)你修改了某數(shù)據(jù)頁

假設(shè)你執(zhí)行了update xxx set xxx where id in (xxx,xxx,xxx,xxx)篡诽;

而符合條件的數(shù)據(jù)行恰巧就在描述信息1崖飘、描述信息66、描述信息67所指向的緩存頁中杈女,那BufferPool中會(huì)發(fā)生什么呢朱浴?

如下圖:

image

你會(huì)看到,被你修改了的緩存頁的描述信息达椰,被添加到了FlushList這個(gè)雙向鏈表中赊琳。

想必看到這里你已經(jīng)知道了,原來FlushList中的節(jié)點(diǎn)存放就是被修改了臟數(shù)據(jù)頁的描述信息塊砰碴。

隨著MySQL被使用的時(shí)間越來越長躏筏,BufferPool的大小就越來越小。等它不夠用的時(shí)候呈枉,就會(huì)將部分LRU中的數(shù)據(jù)頁描述信息移除出去趁尼,這時(shí)如果發(fā)現(xiàn)被移除出來的數(shù)據(jù)頁在FLushList中,就會(huì)觸發(fā)fsync的操作猖辫,觸發(fā)隨機(jī)寫磁盤酥泞。如果該數(shù)據(jù)頁是干凈的,那移除出去就好了啃憎。其他也不用干啥芝囤。

舉個(gè)例子:假設(shè)需要將描述信息66、描述信息67指向的緩存頁落盤辛萍。會(huì)得到下面這張腦圖:

描述信息66悯姊、67指向的緩存頁被刷新進(jìn)磁盤。 同時(shí)從FlushList中將其移除贩毕,然后存入FreeList中悯许。完成一個(gè)循環(huán)

image

當(dāng)然,將臟數(shù)據(jù)頁刷新進(jìn)磁盤的時(shí)機(jī)除了上圖中說的還有好多種情況辉阶。

下面再看一下關(guān)于Buffer Pool的設(shè)置和相關(guān)的優(yōu)化先壕。

五瘩扼、配置Buffer Pool的大小

buffer pool越大,MySQL的性能就越強(qiáng)悍垃僚。你可以像下面這樣配置Buffer Pool的大小集绰。

Copymysql> SET GLOBAL innodb_buffer_pool_size=402653184;

六、配置多個(gè)Buffer Pool的實(shí)例

你可以為MySQL實(shí)例配置多個(gè)Buffer Pool谆棺,每個(gè)Buffer Pool各自負(fù)責(zé)管理一部分緩存頁栽燕,并且有自己獨(dú)立的LRU、Free包券、Flush鏈表。

當(dāng)有多線程并發(fā)請求過來時(shí)炫贤,線程可以在不同的Buffer Pool中執(zhí)行自己的操作溅固,MySQL性能就會(huì)得到很大的提升

在my.d中進(jìn)行配置

Copy[server]
innodb_buffer_pool_size = xxx
innodb_buffer_pool_instances = 4

意思是將總?cè)萘繛閤xx的buffer pool劃分成4個(gè)實(shí)例。每個(gè)實(shí)例都有 xxx/4 的容量兰珍。

參數(shù)innodb_buffer_pool_instances的最大值為64侍郭,并且想讓該參數(shù)生效,innodb_buffer_pool_size容量至少是1G掠河。

可以像下面這樣查看你的MySQL的Buffer Pool實(shí)例狀態(tài)亮元。

image

七、揭秘BufferPool的真實(shí)結(jié)構(gòu)

現(xiàn)實(shí)中Buffer Pool動(dòng)輒就占用好幾G的內(nèi)存唠摹,相對(duì)于直接申請幾G的內(nèi)存完成擴(kuò)容爆捞,MySQL有更優(yōu)雅的實(shí)現(xiàn)方式。

為了實(shí)現(xiàn)動(dòng)態(tài)調(diào)整Buffer Pool的大小勾拉。MySQL設(shè)計(jì)了chunk 機(jī)制煮甥。

image

可以看上圖腦補(bǔ)一下Buffer Pool 以及 Chunk長什么樣。

總的來說:就是將每一個(gè) Buffer Pool Instance 更加細(xì)力度化藕赞。將Buffer Pool拆分成更小的獨(dú)立單元成肘。

每個(gè)Buffer Pool劃分成多個(gè)chunnk,每個(gè)chunk中維護(hù)一部分緩存頁斧蜕、緩存頁的描述信息双霍。同屬于一個(gè)Buffer Pool的chunk共享該Buffer Pool的lru、free批销、flush鏈表洒闸。

塊大小由參數(shù)innodb_buffer_pool_chunk_size控制,默認(rèn)值為 128M

該參數(shù)可以像下面這樣修改:

Copyshell> mysqld --innodb-buffer-pool-chunk-size=134217728

或者通過配置文件自定義

Copy[mysqld]
innodb_buffer_pool_chunk_size=13421772

八均芽、看一看Buffer Pool相關(guān)的參數(shù)#

執(zhí)行命令

Copy> mysql show engine innodb status
image

九顷蟀、如何規(guī)劃你的Buffer Pool大小

推薦將Buffer Pool的總大小設(shè)置為服務(wù)器內(nèi)存的 50%~60%左右

BufferPool總大小 = (chunkSize * bufferPoolInstanceNum)*2

十、Buffer Pool的預(yù)熱機(jī)制

這種機(jī)制實(shí)際上是想讓重啟后的MySQL快速適應(yīng)大規(guī)模的流量請求骡技。

InnoDB 在服務(wù)器關(guān)閉時(shí)為每個(gè)緩沖池保存一部分最近高頻使用的頁面鸣个,并在服務(wù)器啟動(dòng)時(shí)恢復(fù)這些頁面羞反。保存多大比例的緩存頁由參數(shù)innodb_buffer_pool_dump_pct控制。

在啟動(dòng)時(shí)還原緩沖池囤萤,實(shí)際上會(huì)縮短預(yù)熱的時(shí)間昼窗。

你可以通過下面的方式配置該參數(shù)

Copy# 通過命令
SET GLOBAL innodb_buffer_pool_dump_pct=40;

# 通過文件
[mysqld]
innodb_buffer_pool_dump_pct=40

參數(shù)innodb_buffer_pool_dump_at_shutdown控制 MySQL關(guān)閉時(shí)保存緩沖池的狀態(tài),默認(rèn)為on的狀態(tài)涛舍。

啟動(dòng)參數(shù)--innodb-buffer-pool-load-at-startup 表示啟動(dòng)MySQL的時(shí)候恢復(fù)緩沖池中的狀態(tài)澄惊,默認(rèn)也是開啟的。

原文鏈接:https://www.cnblogs.com/ZhuChangwu/p/14018273.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末富雅,一起剝皮案震驚了整個(gè)濱河市掸驱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌没佑,老刑警劉巖毕贼,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蛤奢,居然都是意外死亡鬼癣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門啤贩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來待秃,“玉大人,你說我怎么就攤上這事痹屹≌掠簦” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵志衍,是天一觀的道長驱犹。 經(jīng)常有香客問我,道長足画,這世上最難降的妖魔是什么雄驹? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮淹辞,結(jié)果婚禮上医舆,老公的妹妹穿的比我還像新娘。我一直安慰自己象缀,他們只是感情好蔬将,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著央星,像睡著了一般霞怀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上莉给,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天毙石,我揣著相機(jī)與錄音廉沮,去河邊找鬼。 笑死徐矩,一個(gè)胖子當(dāng)著我的面吹牛滞时,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滤灯,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼坪稽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鳞骤?” 一聲冷哼從身側(cè)響起窒百,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎豫尽,沒想到半個(gè)月后篙梢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拂募,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年庭猩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窟她。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陈症。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖震糖,靈堂內(nèi)的尸體忽然破棺而出录肯,到底是詐尸還是另有隱情,我是刑警寧澤吊说,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布论咏,位于F島的核電站,受9級(jí)特大地震影響颁井,放射性物質(zhì)發(fā)生泄漏厅贪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一雅宾、第九天 我趴在偏房一處隱蔽的房頂上張望养涮。 院中可真熱鬧,春花似錦眉抬、人聲如沸贯吓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽悄谐。三九已至,卻和暖如春库北,著一層夾襖步出監(jiān)牢的瞬間爬舰,已是汗流浹背们陆。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洼专,地道東北人棒掠。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像屁商,于是被迫代替她去往敵國和親烟很。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Schema與數(shù)據(jù)類型優(yōu)化 選擇優(yōu)化的數(shù)據(jù)類型 有幾個(gè)簡單的原則: 更小的通常更好一般情況下使用可以正確存儲(chǔ)數(shù)據(jù)的...
    陳晨_軟件五千言閱讀 3,511評(píng)論 1 65
  • 1. 系統(tǒng)是如何跟MySQL打交道的 系統(tǒng)采用數(shù)據(jù)庫連接池的方式去并發(fā)訪問數(shù)據(jù)庫蜡镶,然后數(shù)據(jù)庫自己其實(shí)也會(huì)維護(hù)一個(gè)連...
    herohua閱讀 937評(píng)論 0 0
  • 基于LRU算法淘汰部分緩存 今天我們接著來分析buffer pool的工作原理雾袱。我們來思考一個(gè)問題,當(dāng)你要執(zhí)行CR...
    為愛放棄一切閱讀 387評(píng)論 0 2
  • 表情是什么官还,我認(rèn)為表情就是表現(xiàn)出來的情緒芹橡。表情可以傳達(dá)很多信息。高興了當(dāng)然就笑了望伦,難過就哭了林说。兩者是相互影響密不可...
    Persistenc_6aea閱讀 124,168評(píng)論 2 7
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險(xiǎn)厭惡者,不喜歡去冒險(xiǎn)屯伞,但是人生放棄了冒險(xiǎn)腿箩,也就放棄了無數(shù)的可能。 ...
    yichen大刀閱讀 6,033評(píng)論 0 4