日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql内存机制_MySQL内存管理机制

發布時間:2025/3/17 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql内存机制_MySQL内存管理机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. BufferPool

What is BufferPool?

MySQL InnoDB Buffer Pool,MySQL InnoDB 緩沖池。里面緩存著大量數據(數據頁),使 CPU 讀取或寫入數據時,不直接和低速的磁盤打交道,直接和緩沖區進行交互,從而解決了因為磁盤性能慢導致的數據庫性能差的問題。

Why need BufferPool?

buffer pool 最主要的功能便是加速讀和加速寫。

加速讀就是當需要訪問一個數據頁的時候,如果這個頁已經在緩存池中,那么就不再需要訪問磁盤,直接從緩沖池中就能獲取這個頁面的內容。

加速寫就是當需要修改一個數據頁的時候,先將這個頁在緩沖池中進行修改,記下相關的 redo log,這個頁的修改就算已經完成了。至于這個被修改的頁什么時候真正刷新到磁盤,這個是 buffer pool 后臺刷新線程來完成的。

How implemented?

所有從磁盤加載進內存的數據頁,都會通過這個buffer pool管理起來。對應在代碼的中的結構體為buf_pool_t。在MySQL中通常會有多個buffer pool instance,這是為了減少多線程并發訪問時,buffer pool鎖等待的開銷。

BufferPool由buf_pool, buf_chunk, buf_block和buf_page組成,結構如下:

Code?

struct buf_pool_t {

buf_chunk_t *chunks; /*!< buffer pool chunks */

hash_table_t *page_hash; /*!< hash table of buf_page_t or

buf_block_t file pages,

buf_page_in_file() == TRUE,

indexed by (space_id, offset).

page_hash is protected by an

array of mutexes. */

UT_LIST_BASE_NODE_T(buf_page_t) flush_list;

/*!< base node of the modified block

list */

UT_LIST_BASE_NODE_T(buf_page_t) free;

/*!< base node of the free

block list */

UT_LIST_BASE_NODE_T(buf_page_t) LRU;

/*!< base node of the LRU list */

/* ... */

}

struct buf_chunk_t {

ulint size; /*!< size of frames[] and blocks[] */

unsigned char *mem; /*!< pointer to the memory area which

was allocated for the frames */

buf_block_t *blocks; /*!< array of buffer control blocks */

/* ... */

}

struct buf_block_t {

buf_page_t page; /*!< page information; this must

be the first field, so that

buf_pool->page_hash can point

to buf_page_t or buf_block_t */

byte *frame; /*!< pointer to buffer frame which

is of size UNIV_PAGE_SIZE, and

aligned to an address divisible by

UNIV_PAGE_SIZE */

/* ... */

}

class buf_page_t {

public:

/** @name General fields

None of these bit-fields must be modified without holding

buf_page_get_mutex() [buf_block_t::mutex or

buf_pool->zip_mutex], since they can be stored in the same

machine word. */

/* @{ */

/** Page id. */

page_id_t id;

/** Page size. */

page_size_t size;

/** Count of how manyfold this block is currently bufferfixed. */

uint32_t buf_fix_count;

/** type of pending I/O operation. */

buf_io_fix io_fix;

/** Block state. @see buf_page_in_file */

buf_page_state state;

/* ... */

}

2. 頁面管理機制

InnoDB 基于 LRU 算法管理 buffer pool 中的數據頁。一般情況下 list 頭部存放的是熱數據,就是所謂的 young page(最近經常訪問的數據),list 尾部存放的就是 old page(最近不被訪問的數據)。

LRU List:緩存了所有讀入內存的數據頁。包含三類:

未修改的頁面,可以從該鏈表中摘除,然后移到 Free List 中;

已修改還未刷新到磁盤的頁面;

已修改且已經刷新到磁盤的頁面,可并為第一類。

Free List:空閑內存頁列表,需要裝載(緩存)磁盤上數據頁的時候,從此列表取內存塊。

Flush List:在內存中被修改但還沒有刷新到磁盤的數據頁(臟頁)鏈表,內存中的數據跟對應磁盤上的數據不一致,屬于該鏈表的頁同樣存在于 LRU List 中,但反之未必。

How read a page?

當訪問的頁面在緩存池中命中,則直接從緩沖池中訪問該頁面。如果沒有命中,則需要將這個 page 從磁盤上加載到緩存池,因此需要在緩存池中的 Free List 中找一個空閑的內存頁來緩存這個從磁盤讀入的 page。

但存在空閑內存頁被使用完的情況,不保證一定有空閑的內存頁。假如 Free List 為空,則需要想辦法產生空閑的內存頁。 首先是在 LRU List 中找可以替換的內存頁,查找方向是從列表的尾部開始找,如果找到可以替換的 page,將其從 LRU List 中摘除,加入 Free List,然后再去 Free List 中找空閑的內存頁。第一次查找最多只掃描 100 個 page,循環進行到第二次時,查找深度就是整個 LRU List。這就是 LRU List 的頁面淘汰機制。

如果在 LRU List 中沒有找到可以替換的頁,則進行單頁刷新,將臟頁刷新到磁盤后,再將釋放的內存頁加入到 Free List,最后再去 Free List 取。為什么只做單頁刷新呢?因為它的目的是獲取空閑內存頁,進行臟頁刷新是不得已而為之,所以只會進行一個頁的刷新,目的是為了盡快的獲取空閑內存頁。

因為 Free List 是一個公共的鏈表,所有的用戶線程都可以使用,存在爭用的情況。因此,自己產生的空閑內存頁有可能會剛好被其它線程所使用,因此用戶線程可能會重復執行上面的查找流程,直到找到空閑的內存頁為止。

通過數據頁訪問機制,可以知道當無空閑頁時產生空閑頁就成為了一個必須要做的事情。

如果需要通過刷新臟頁來產生空閑頁或者需要掃描整個 LRU List 來產生空閑頁,查找空閑頁的時間就會延長,這是一個 bad case。

因此,innodb buffer pool 中存在大量可以替換的頁,或者 Free List 中一直存在著空閑內存頁,對快速獲取空閑內存頁就起到了決定性的作用。

而在 innodb buffer pool 的機制中,是采用何種方式來產生空閑內存頁以及可以替換的內存頁呢?這就是下面要講的內容——臟頁刷新策略。

How to flush a dirty page?

MySQL線程后臺會有flush線程,定期地將flush list的臟頁flush到磁盤上,這樣可以減輕check point的開銷,和頁面替換時,那些被替換頁面的flush開銷,而使得讀取頁面時間增長。flush list的頁面根據修改的時間從新到老進行排序,也即是最新的修改,在flush list的頭部,最老的修改在flush list的尾部。當flush時,從尾部取page flush到磁盤上。這樣的邏輯是跟checkpoint保持一致,checkpoint的流程也是從老到新一步步持久化page,所以可以加快checkpoint。

When to flush dirty page?

后臺線程定期刷;

redo log 寫滿了(強制刷);

內存不足(強制刷)。

參考:

總結

以上是生活随笔為你收集整理的mysql内存机制_MySQL内存管理机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。