MySQL源碼學習(二) Buffer Pool

      網(wǎng)友投稿 1115 2025-04-03

      Mysql源碼學習(二) Buffer Pool


      Buffer Pool是innodb的核心組件之一,所有數(shù)據(jù)的讀取,都會先放到Buffer Pool中,再讀取出來,而不是直接讀取datafile文件。那么對于類似筆者這樣的新手來說,從哪里開始閱讀buffer pool的代碼呢?在源代碼中,幾乎搜不到”buffer pool”這樣的關鍵字?

      1.?????? 從buf_pool_t開始

      Mysql代碼庫的src/storage/innobase/include目錄下,大家可以找到buf0buf.h頭文件,這里就是存放buffer pool核心管理結構的地方。在頭文件中, struct buf_pool_t這個定義,就是這個關鍵結構體。大家可以其中看到一個一個熟悉關鍵字:”LRU”,沒錯,大名鼎鼎的LRU鏈表就在這其中,但還有其他很多的字段,在這里不一一展開,后面會通過與LRU鏈表最相關的幾個鏈表逐一展開。

      2.?????? 6大鏈表

      圖1 Buffer Pool 6大鏈表

      如圖1所示,buf_pool_t結構體中的6個關鍵字段: free, LRU, unzip_LRU, flush_list, zip_clean, zip_free分別對應了6大鏈表。其中:

      l? free

      它是在系統(tǒng)初始化階段bufpool進行初始化后唯一顯式調用鏈表初始化函數(shù)進行init操作的唯一bufpool鏈表。系統(tǒng)內的第一個LRU鏈表塊,必然是從free鏈表中獲取到的,當flush模塊臟頁刷新完成,LRU鏈表節(jié)點就會被清除或者移動到LRU鏈表結尾等待清除,清除LRU之后的節(jié)點仍舊是回歸到free鏈表內。

      l? LRU

      當有LRU鏈表為空時,必然從free鏈表獲取空閑節(jié)點,并進行異步IO讀將頁讀入bufpool,并加入LRU鏈表,LRU鏈表長度過大的情況下,會進行尾部刷新,刷新失敗會進行更徹底的直接通過LRU進行臟頁刷新(BUF_FLUSH_LRU方式),flush鏈表節(jié)點得到釋放臟頁完成刷新,并同時把LRU鏈表的臟塊也完成移除

      l? Unzip_LRU

      本鏈表實際是LRU鏈表的一個子集,在壓縮頁控制塊(buf_page_struct)中的壓縮頁需要進行解壓縮以進行各種記錄級讀寫操作時,該鏈表將發(fā)揮作用,因此可以說,插入到了unzip_LRU鏈表就一定頁在LRU鏈表中,反之則未必。

      l? Flush_list

      l? zip_clean

      本鏈表以目前的源代碼來看僅用于調試功能。

      l? zip_free

      bufpool6大鏈表中最特殊的一個,鏈表的根節(jié)點可以看做“是一個指針數(shù)組”,伙伴系統(tǒng)的精髓就在于按照2的倍數(shù)進行緊鄰內存塊的合并和拆分,進而達到高效管理、代碼復雜度低的效果。這個指針數(shù)組按照塊大小實際包含4層,1024,2048,4096和8192,每一層基結點只管理同類大小的塊。

      從圖我們可以看出,LRU是整個Buffer Pool的核心,因此我們以LRU為線索展開說明,zip_clean和zip_free較為特殊,本文暫不做詳細說明,

      3.?????? LRU分配

      從LRU和free的說明可以知道,LRU都是從free鏈表中獲得真正的內存空間的。分配的函數(shù)入口就在:storage/innobase/buf目錄下的buf0lrn.cc文件中的 buf_LRU_get_free_block函數(shù)

      圖2 buf_LRU_get_free_block主要流程

      圖2流程中標志了分配的整個流程,但并不是所有情況下,都會完全執(zhí)行這個流程,例如:當free鏈表仍未被使用完時,執(zhí)行完buf_LRU_get_free_only后就會返回。如果free鏈表已被用完,或者buf_LRU_get_free_only返回為NULL,則會執(zhí)行buf_LRU_scan_and_free_block,從已有的LRU列表中找到一個block然后釋放。buf_LRU_scan_and_free_block會在第4小節(jié)中進行闡述

      l? buf_LRU_get_free_only

      返回一個空閑的block,這個block來自于free鏈表,如果free鏈表為空(內存耗盡),則返回NULL

      圖3 buf_LRU_get_free_only函數(shù)主體

      從圖3中我們可以看到,首先會從free鏈表的頭部開始便利,找到一個可用的block,并把block的狀態(tài)設置為BUF_BLOCK_READY_FOR_USE的狀態(tài),然后返回。

      圖4 若無法從free鏈表中獲取到block,則先釋放一個LRU鐘的block

      這里不得不提一下buf_LRU_get_free_block中的這段代碼,如果是第一次進行掃描,則會從LRU的尾部開始掃描(LRU的特點,這里可以提升效率),但是如果不是第一次掃描,則會掃描整個LRU。但是如果掃描了一次,還是沒找到呢?看下圖

      圖5 強制刷新一個page,并將page放到free鏈表中

      如果掃描超過1次沒有找到能釋放的LRU,則會讓thread sleep一段時間,等待page clean刷一些數(shù)據(jù)到磁盤上,然后會強制執(zhí)行一次刷新,將1個page刷到磁盤上,然后再放到free鏈表中。這里要注意,LRU釋放掉一個page后,并不會直接使用這個page,而是將它先放回free鏈表,然后再按正常流程拿過來。

      4.?????? LRU釋放

      圖6 LRU釋放流程

      LRU的釋放,可以看到LRU的釋放,會從unzip_LRU鏈表和common_LRU鏈表中進行釋放。unzip_LRU我們上面已經介紹,那么common_LRU是什么呢?其實就是LRU本身。另外從這里也可以看出,unzip_LRU就是LRU的一個子集,釋放unzip_LRU就是釋放LRU本身。

      MySQL源碼學習(二) Buffer Pool

      我們再進入buf_LRU_free_from_common_LRU_list函數(shù),我們可以看到:

      圖7 buf_LRU_free_from_common_LRU_list函數(shù)主體

      所謂釋放LRU,是必須要保證這個page是clean的,如果page不是clean的,就需要刷臟。這也是為什么在分配過程中,有可能出現(xiàn)找不到能釋放的page的原因。

      更深入的釋放流程涉及到buffer pool的內存管理,我們會在下次再進行深入探討

      RDS-MYSQL 云數(shù)據(jù)庫 MySQL RDS MySQL MySQL

      版權聲明:本文內容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內刪除侵權內容。

      上一篇:Excel如何做甘特圖
      下一篇:企業(yè)設備管理(企業(yè)設備管理培訓課程)
      相關文章
      综合一区自拍亚洲综合图区| 亚洲区小说区图片区QVOD| 久久久久亚洲AV无码专区网站 | 亚洲人成网站在线观看播放动漫| 亚洲综合亚洲综合网成人| 亚洲av午夜精品无码专区| 亚洲一区中文字幕久久| 国产亚洲一区二区精品| 久久精品国产亚洲Aⅴ蜜臀色欲| 亚洲国产精品成人久久蜜臀| 国产精品亚洲专区一区| 亚洲AV网站在线观看| 亚洲国产综合精品一区在线播放| 亚洲AV无码一区二三区| 亚洲麻豆精品国偷自产在线91| 亚洲无码精品浪潮| 国产亚洲av片在线观看18女人 | 亚洲区日韩区无码区| 亚洲欧洲日产国码高潮αv| 亚洲日本va午夜中文字幕久久| 亚洲免费日韩无码系列| 国产美女亚洲精品久久久综合| 国产亚洲精品a在线无码| 亚洲va久久久噜噜噜久久| 亚洲国产一区国产亚洲| 久久亚洲AV成人无码软件| 亚洲性无码av在线| 亚洲人成电影在线观看网| 亚洲日韩中文字幕无码一区| 亚洲av无码成人影院一区| 少妇亚洲免费精品| 国产亚洲美日韩AV中文字幕无码成人 | 亚洲五月激情综合图片区| 亚洲黄网在线观看| 亚洲一区二区三区无码国产| 亚洲色偷偷综合亚洲AV伊人蜜桃 | 亚洲精品国产成人99久久| 亚洲日韩中文字幕天堂不卡| 日韩亚洲国产综合高清| 欧美激情综合亚洲一二区| 亚洲午夜日韩高清一区|