緩沖池是主存盤器中的一個區域,在訪問 table 和索引資料時InnoDB
會對其進行快取,緩沖池允許直接從記憶體中訪問頻繁使用的資料,從而加快處理速度,在專用服務器上,通常將高達 80% 的物理記憶體分配給緩沖池,
為了高效處理大量讀取操作,緩沖池被劃分為可以容納多行資料的頁面,為了有效管理快取,緩沖池被實作為頁面的鏈接串列;通過 LRU(least recently used)演算法的變體將很少使用的資料從快取中淘汰出去,
了解如何利用緩沖池將頻繁訪問的資料保留在記憶體中是MySQL調優的重要方面之一,
緩沖池 LRU 演算法
緩沖池使用一種最近最少使用(LRU)演算法的變體作為串列進行管理,當需要空間以將新頁面添加到緩沖池時,最近最少使用的頁面會被移除,并將新頁面添加到串列的中間,這種中點插入策略將串列視為兩個子串列:
- 在前面是最近訪問過的新("young")頁面的子串列;
- 在尾部是最近較少被訪問的舊("old")頁面子串列,
緩沖池串列如下圖所示:
該演算法將頻繁使用的頁面保留在新頁面子串列中,舊頁面子串列則包含較少被使用的頁面,這些頁面是可能被淘汰(eviction)的候選頁面,
默認情況下,演算法運行如下:
- 緩沖池的 3/8 專門用于舊頁面子串列,
- 串列的中點是新頁面子串列的尾部與舊頁面子串列的頭部相遇的邊界位置,
- 當
InnoDB
將一個頁面讀入緩沖池時,它最扯訓插入到中點位置(舊頁面子串列的頭部),一個頁面可以被讀取,因為它是用戶發起的操作(例如 SQL 查詢)所必需的,或者是InnoDB
自動執行的預讀(read-ahead)操作的一部分, - 訪問舊頁面子串列中的一個頁面會使其變為"young",并將其移動到新頁面子串列的開頭,如果頁面由于用戶發起的操作而被讀取,則將立即進行首次訪問,并且頁面會被標記為"young",如果頁面是由于預讀操作而被讀取,則第一次訪問不會立即發生,并且在該頁面被淘汰之前可能根本不會發生,
- 隨著資料庫的運行,緩沖池中未被訪問的頁面會通過向串列的尾部移動而"老化",新頁面子串列和舊頁面子串列中的頁面都會隨著其他頁面的更新而老化,舊頁面子串列中的頁面也會隨著在中點插入頁面而老化,最終,一個長時間未被使用的頁面會到達舊頁面子串列的尾部并被淘汰,
默認情況下,通過查詢讀取的頁面會立即移動到新頁面子串列中,這意味著它們在緩沖池中停留的時間更長,例如,對于執行mysqldump操作或不帶WHERE
子句的SELECT
陳述句進行的表掃描,可能會將大量資料帶入緩沖池,并淘汰相同數量的較舊資料,即使新資料永遠不會再次使用,同樣地,由預讀取后臺執行緒加載且僅訪問一次的頁面會移動到新頁面子串列的開頭,這些情況會將頻繁使用的頁面推入舊頁面子串列,使其面臨淘汰的風險,關于優化這種行為的資訊,請參閱"使緩沖池具有掃描抵抗力"和"配置 InnoDB 緩沖池預取(預讀)",
InnoDB
標準監視器(Standard Monitor)的輸出在BUFFER POOL AND MEMORY
部分中包含了幾個與緩沖池 LRU 演算法操作有關的欄位,有關詳細資訊,請參閱使用 InnoDB 標準監視器監控緩沖池,
緩沖區配置
您可以配置緩沖池的各個方面以提高性能,
- 理想情況下,您應該將緩沖池的大小設定為盡可能大的值,同時確保為服務器上的其他行程留有足夠的記憶體,以避免過多的頁面交換(paging),緩沖池越大,
InnoDB
就更像是一個記憶體資料庫,從磁盤讀取一次資料,然后在后續讀取從記憶體中訪問資料,有關詳細資訊,請參閱"配置 InnoDB 緩沖池大小", - 在具有足夠記憶體的64位系統上,可以將緩沖池分成多個部分,以最大程度地減少并發操作之間對記憶體結構的爭用,有關詳細資訊,請參閱"配置多個緩沖池實體",
- 您可以將頻繁訪問的資料保留在記憶體中,而不受會將大量不經常訪問的資料帶入緩沖池的操作突然活動的影響,有關詳細資訊,請參閱"使緩沖池具有掃描抵抗力",
- 您可以控制何時以及如何執行預讀請求,以異步方式將頁面預取到緩沖池中,從而期望這些頁面很快會被使用,有關詳細資訊,請參閱"配置 InnoDB 緩沖池預取(預讀)",
- 您可以控制何時進行后臺重繪,以及是否根據作業負載動態調整重繪速率,有關詳細資訊,請參閱"配置緩沖池重繪",
- 您可以配置
InnoDB
保存當前的緩沖池狀態的方式,以避免服務器重新啟動后的漫長預熱時間,有關詳細資訊,請參閱"保存和恢復緩沖池狀態",
使用 InnoDB 標準監視器監控緩沖池
可以使用SHOW ENGINE INNODB STATUS訪問InnoDB
標準監視器輸出提供的有關緩沖池操作的指標,緩沖池指標位于InnoDB
標準監視器輸出的BUFFER POOL AND MEMORY
部分:
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 2198863872
Dictionary memory allocated 776332
Buffer pool size 131072
Free buffers 124908
Database pages 5720
Old database pages 2071
Modified db pages 910
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 4, not young 0
0.10 youngs/s, 0.00 non-youngs/s
Pages read 197, created 5523, written 5060
0.00 reads/s, 190.89 creates/s, 244.94 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not
0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read
ahead 0.00/s
LRU len: 5720, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
下表描述了InnoDB
標準監視器報告的緩沖池指標,
注:InnoDB
標準監視器輸出中提供的每秒平均值是基于自上次列印InnoDB
標準監視器輸出以來經過的時間計算的,
InnoDB 緩沖池指標如下表所示:
Name | Description |
---|---|
Total memory allocated | 為緩沖池分配的總記憶體(以位元組為單位), |
Dictionary memory allocated | 為InnoDB 資料字典分配的總記憶體(以位元組為單位), |
Buffer pool size | 分配給緩沖池的頁面總大小, |
Free buffers | 緩沖池空閑串列的頁面總大小, |
Database pages | 緩沖池 LRU 串列的頁面總大小, |
Old Database pages | 緩沖池舊 LRU 子串列的頁面總大小, |
Modified db pages | 當前在緩沖池中修改的頁面數, |
Pending reads | 等待讀入緩沖池的緩沖池頁面數, |
Pending writes LRU | 從 LRU 串列底部等待寫入緩沖池中舊臟頁的數量, |
Pending writes flush list | 檢查點期間要重繪的緩沖池頁面數, |
Pending writes single page | 緩沖池中暫掛的獨立頁面寫入數, |
Pages made young | 緩沖池 LRU 串列中變年輕的頁面總數(移至“新”頁面的子串列的開頭), |
Pages made not young | 緩沖池 LRU 串列中沒有變年輕的頁面總數(保留在“舊”頁面子串列中沒有年輕的頁面), |
youngs/s | 在緩沖池 LRU 串列中,平均每秒訪問舊頁面并使其變為年輕頁面的次數,有關更多資訊,請參閱此表格后面的注釋, |
non-youngs/s | 在緩沖池 LRU 串列中,平均每秒訪問舊頁面并未導致頁面變為年輕頁面的次數,有關更多資訊,請參閱此表格后面的注釋, |
Pages read | 從緩沖池讀取的頁面總數, |
Pages created | 在緩沖池中創建的頁面總數, |
Pages written | 從緩沖池寫入的頁面總數, |
reads/s | 平均每秒讀取的緩沖池頁面數, |
creates/s | 平均每秒創建的緩沖池頁面數, |
writes/s | 平均每秒緩沖池頁面寫入數, |
Buffer pool hit rate | 從緩沖池讀取的頁面與從磁盤存盤讀取的頁面之間的緩沖池頁面命中率, |
young-making rate | 頁面訪問導致頁面變為年輕頁面的平均命中率,有關更多資訊,請參閱此表格后面的注釋, |
not (young-making rate) | 頁面訪問未使頁面變年輕的平均命中率,有關更多資訊,請參見此表格后面的注釋, |
Pages read ahead | 平均每秒的預讀操作次數, |
Pages evicted without access | 平均每秒從緩沖池中淘汰而被訪問的頁面數量, |
Random read ahead | 平均每秒隨機預讀操作次數, |
LRU len | 緩沖池 LRU 串列的頁面總大小, |
unzip_LRU len | 緩沖池 unzip_LRU 串列的長度(以頁面為單位), |
I/O sum | 訪問的緩沖池 LRU 串列頁面總數, |
I/O cur | 當前間隔內訪問的緩沖池 LRU 串列頁面總數, |
I/O unzip sum | 已訪問的緩沖池 unzip_LRU 串列頁面的總數, |
I/O unzip cur | 當前時間間隔內已訪問的緩沖池 unzip_LRU 串列頁面的總數, |
Notes:
-
年輕頁面生成速率
youngs/s
指標僅適用于舊頁面,它基于頁面的訪問次數而不是頁面數計算,對于給定頁面,可能會有多次訪問,所有訪問都會被計算在內,如果在沒有進行大規模掃描的情況下youngs/s
非常低,則可能需要減少延遲時間或增加用于舊子串列的緩沖池百分比,增加百分比會使舊子串列變大,因此需要更長的時間才能將該子串列中的頁面移動到尾部,從而增加這些頁面再次被訪問并成為年輕頁面的可能性,請參閱“使緩沖池抗掃描”, -
非年輕頁面生成速率
non-youngs/s
指標僅適用于舊頁面,它基于頁面的訪問次數而不是頁面數計算,對于給定頁面,可能會有多次訪問,所有訪問都會被計算在內,如果在執行大型表掃描(以及較高的youngs/s
)時沒有看到更高的非年輕頁面生成速率值non-youngs/s
,請增加延遲值,請參閱“使緩沖池抗掃描”, -
年輕頁面生成率
young-making
考慮了所有緩沖池頁面的訪問,而不僅僅是舊子串列中頁面的訪問,年輕頁面生成率young-making
和非年輕頁面生成率non-youngs/s
通常不會累加到整體緩沖池命中率上,在舊子串列中的頁面命中會導致頁面移動到新子串列,但是新子串列中的頁面命中只有當它們距離串列頭部一定距離時才會移動到串列頭部, -
非(年輕頁面生成率)
not (young-making rate)
是指由于未達到由innodb_old_blocks_time定義的延遲時間,或由于新子串列中的頁面命中未導致頁面移動到頭部,而導致頁面訪問未使頁面變為年輕頁面的平均命中率,此率考慮了所有緩沖池頁面的訪問,而不僅僅是舊子串列中頁面的訪問,
緩沖池服務器狀態變數和INNODB_BUFFER_POOL_STATS表提供了許多與InnoDB
Standard Monitor 輸出中相同的緩沖池指標,有關更多資訊,請參閱示例“查詢INNODB_BUFFER_POOL_STATS table”,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/555557.html
標籤:其他
上一篇:現代C++學習指南-標準庫
下一篇:返回列表