MySQL記憶體管理
標籤:MySQL
標籤:MySQL結構
標籤:MySQL記憶體管理
1. Buffer Pool主要的基礎結構buf_pool_t、buf_block_t和buf_page_t。
(1).
Buffer Pool例項,大小等於innodb_buffer_pool_size/innodb_buffer_pool_instances,
每個Buffer Pool Instance都有自己的鎖,訊號量,物理塊(Bufferchunks)以及邏輯連結串列(List)。
即各個instance之間沒有競爭關係,可以併發讀取與寫入。所有instance的物理塊(Buffer chunks)在資料庫啟動的時候被分配,直到資料庫關閉記憶體才予以釋放。
每個Buffer Pool Instance有一個page hash連結串列,透過它,使用space_id和page_no就能快速找到已經被讀入記憶體的資料頁,而不用線性遍歷LRU List去查詢。
page hash是為了避免掃描LRU List。
struct buf_pool_t { //儲存Buffer Pool Instance級別的資訊
...
ulint instance_no; //當前buf_pool所屬instance的編號
ulint curr_pool_size; //當前buf_pool大小
buf_chunk_t *chunks; //當前buf_pool中包含的chunks
hash_table_t *page_hash; //快速檢索已經快取的Page
UT_LIST_BASE_NODE_T(buf_page_t) free; //空閒Page連結串列
UT_LIST_BASE_NODE_T(buf_page_t) LRU; //Page快取連結串列,LRU策略淘汰
UT_LIST_BASE_NODE_T(buf_page_t) flush_list; //還未Flush磁碟的髒頁儲存連結串列
BufListMutex XXX_mutex; //各個連結串列的互斥Mutex
...
}
(2).
Buffer chunks是每個Buffer Pool Instance中實際的物理儲存塊陣列,一個Buffer Pool Instance中有一個或多個chunk,每個chunk的大小預設為128MB,最小為1MB,且這個值在8.0中時可以動態調整生效的。
Buffer Chunks是最低層的物理塊,在啟動階段從作業系統申請,直到資料庫關閉才釋放。
每個Buffer chunk中包含一個buf_block_t的blocks陣列(即Page)。
blocks陣列中的每個元素buf_block_t是一個資料頁結構體,其中包含了一個指向具體資料頁的*frame指標,以及具體的控制體buf_page_t。
struct buf_block_t { //Page控制體
buf_page_t page; //這個欄位必須要放到第一個位置,這樣才能使得buf_block_t和buf_page_t的指標進行轉換
byte *frame; //指向真正儲存資料的Page
BPageMutex mutex; //block級別的mutex
...
}
(3).
class buf_page_t {
...
page_id_t id; //page id
page_size_t size; //page 大小
ib_uint32_t buf_fix_count; //用於併發控制
buf_io_fix io_fix; //用於併發控制
buf_page_state state; //當前Page所處的狀態,後續會詳細介紹
lsn_t newest_modification; //當前Page最新修改lsn
lsn_t oldest_modification; //當前Page最老修改lsn,即第一條修改lsn
...
}
(4).buf_page_state,這是一個列舉型別,標識了每個Page所處的狀態,在讀取和訪問時都會對應不同的狀態轉換。
enum buf_page_state {
BUF_BLOCK_POOL_WATCH, //註釋是給Purge使用的
BUF_BLOCK_ZIP_PAGE, //壓縮Page狀態
BUF_BLOCK_ZIP_DIRTY, //壓縮頁髒頁狀態
BUF_BLOCK_NOT_USED, //儲存在Free List中的Page
BUF_BLOCK_READY_FOR_USE, //當呼叫到buf_LRU_get_free_block獲取空閒Page,此時被分配的Page就處於這個狀態
BUF_BLOCK_FILE_PAGE, //正常被使用的狀態,LRU List中的Page都是這個狀態
BUF_BLOCK_MEMORY, //用於儲存非使用者資料,比如系統資料的Page處於這個狀態
BUF_BLOCK_REMOVE_HASH //在Page從LRU List和Flush List中被回收並加入Free List時,需要先從Page_hash中移除,此時Page處於這個狀態
};
2. 頁連結串列
連結串列節點是資料頁的控制體(控制體中有指標指向真正的資料頁),連結串列中的所有節點都有同一的屬性,引入其的目的是方便管理。
以下所有的連結串列中的每個節點都是資料頁控制體(buf_page_t)。
2.1
Free List:如其名,Free List中存放的都是未曾使用的空閒Page,InnoDB需要Page時從Free List中獲取,如果Free List為空,即沒有任何空閒Page,則會從LRU List和Flush List中透過淘汰舊Page和Flush髒Page來回收Page。在InnoDB初始化時,會將Buffer chunks中的所有Page加入到Free List中。
2.2
LRU List:所有從資料檔案中新讀取進來的Page都會快取在LRU List,並透過LRU策略對這些Page進行管理。LRU List實際劃分為Young和Old兩個部分,其中Young區儲存的是較熱的資料,Old區儲存的是剛從資料檔案中讀取出來的資料,如果LRU List的長度小於512,則不會將其拆分為Young和Old區。當InnoDB讀取Page時,首先會從當前Buffer Pool Instance的page_hash查詢,並分為三種情況來處理:
如果在page_hash找到,即Page在LRU List中,則會判斷Page是在Old區還是Young區,如果是在Old區,在讀取完Page後會把它新增到Young區的連結串列頭部.
如果在page_hash找到,並且Page在Young區,需要判斷Page所在Young區的位置,只有Page處於Young區總長度大約1/4的位置之後,才會將其新增到Young區的連結串列頭部。
如果未能在page_hash找到,則需要去資料檔案中讀取Page,並將其新增到Old區的頭部。
LRU List採用非常精細的LRU淘汰策略來管理Page,並且用以上機制避免了頻繁對LRU 連結串列的調整。
2.3
Flush List:所有被修改過且還沒來得及被flush到磁碟上的Page(髒頁),都會被儲存在這個連結串列中。所有儲存在Flush List上的資料都會在LRU List中,但在LRU List中的資料不一定都在Flush List中。在Flush List上的每個Page都會儲存其最早修改的lsn,即oldest_modification,雖然一個Page可能被修改多次,但只記錄最早的修改。Flush List上的Page會按照其各自的oldest_modification進行降序排序,連結串列尾部儲存oldest_modification最小的Page,在需要從Flush List中回收Page時,從尾部開始回收。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25380026/viewspace-2747123/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MYSQL的記憶體管理方法MySql記憶體
- 記憶體管理 記憶體管理概述記憶體
- MySQL記憶體管理,記憶體分配器和作業系統MySql記憶體作業系統
- 記憶體管理篇——實體記憶體的管理記憶體
- 【記憶體管理】記憶體佈局記憶體
- 記憶體管理兩部曲之實體記憶體管理記憶體
- Java的記憶體 -JVM 記憶體管理Java記憶體JVM
- Go:記憶體管理與記憶體清理Go記憶體
- 【記憶體管理】Oracle AMM自動記憶體管理詳解記憶體Oracle
- 記憶體管理兩部曲之虛擬記憶體管理記憶體
- JavaScript 記憶體管理JavaScript記憶體
- iOS 記憶體管理iOS記憶體
- Android記憶體管理Android記憶體
- OC記憶體管理記憶體
- 記憶體管理-swMemoryGlobal記憶體
- Flink記憶體管理記憶體
- 【記憶體管理】Oracle如何使用ASMM自動共享記憶體管理記憶體OracleASM
- linux記憶體管理(一)實體記憶體的組織和記憶體分配Linux記憶體
- MySQL InnoDB記憶體配置MySql記憶體
- mysql最大表記憶體MySql記憶體
- Linux實體記憶體管理Linux記憶體
- iOS 記憶體管理MRCiOS記憶體
- “理解”iOS記憶體管理iOS記憶體
- iOS 記憶體管理研究iOS記憶體
- 01記憶體管理-概述記憶體
- python的記憶體管理Python記憶體
- 管理 Bitmap 記憶體(譯)記憶體
- C++記憶體管理C++記憶體
- CF的記憶體管理。記憶體
- Windows記憶體管理-分段Windows記憶體
- JavaScript的記憶體管理JavaScript記憶體
- HotSpot JVM 記憶體管理HotSpotJVM記憶體
- Linux記憶體洩露案例分析和記憶體管理分享Linux記憶體洩露
- Spark學習——記憶體管理Spark記憶體
- Objective-C記憶體管理Object記憶體
- 技術分享:記憶體管理記憶體
- Java記憶體管理機制Java記憶體
- Objective-C 記憶體管理Object記憶體