緩衝池是主記憶體中的一個區域,InnoDB
會在其中快取表格和索引資料,以便存取。緩衝池允許直接從記憶體存取常用的資料,進而加快處理速度。在專用伺服器上,通常會將高達 80% 的實體記憶體指派給緩衝池。
為了提高大量讀取操作的效率,緩衝池會分割成可能包含多列的頁面。為了提高快取管理的效率,緩衝池會實作為頁面的連結清單;不常用的資料會使用最近最少使用 (LRU) 演算法的變體從快取中淘汰。
了解如何利用緩衝池將常用的資料保留在記憶體中,是 MySQL 調整的重要一環。
緩衝池是使用 LRU 演算法的變體作為清單來管理。當需要空間將新頁面新增至緩衝池時,最近最少使用的頁面會被逐出,而新頁面會新增至清單的中間。這種中點插入策略會將清單視為兩個子清單
在開頭,是最近存取的新(「年輕」)頁面的子清單
在結尾,是最近較少存取的舊頁面子清單
此演算法會將常用的頁面保留在新的子清單中。舊的子清單包含較少使用的頁面;這些頁面是淘汰的候選者。
依預設,此演算法的運作方式如下
緩衝池的 3/8 會用於舊的子清單。
清單的中點是新的子清單尾部與舊的子清單頭部交會的邊界。
當
InnoDB
將頁面讀取到緩衝池時,會將其初始插入到中點 (舊的子清單的頭部)。頁面會讀取是因為使用者起始的操作 (例如 SQL 查詢) 需要它,或是作為InnoDB
自動執行的預讀操作的一部分。存取舊子列表中的頁面會使其「變年輕」,並將其移至新子列表的頭部。如果頁面是因為使用者發起的作業而讀取,則第一次存取會立即發生,並且該頁面會變年輕。如果頁面是因為預讀作業而讀取,則第一次存取不會立即發生,並且可能會在頁面被逐出之前根本沒有發生。
隨著資料庫運作,緩衝池中未被存取的頁面會藉由向列表尾部移動而「老化」。新舊子列表中的頁面都會隨著其他頁面變新而老化。舊子列表中的頁面也會隨著頁面插入中點而老化。最終,一個保持未使用的頁面會到達舊子列表的尾部並被逐出。
預設情況下,查詢讀取的頁面會立即移至新子列表中,這表示它們會在緩衝池中停留較長時間。例如,為 mysqldump 作業或沒有 WHERE
子句的 SELECT
陳述式執行的資料表掃描,可能會將大量資料帶入緩衝池,並逐出等量的舊資料,即使新資料永遠不會再被使用。同樣地,由預讀背景執行緒載入且僅存取一次的頁面也會被移至新列表的頭部。這些情況可能會將頻繁使用的頁面推到舊子列表中,在那裡它們會受到逐出的影響。有關優化此行為的資訊,請參閱第 17.8.3.3 節「使緩衝池具有掃描抵抗能力」和第 17.8.3.4 節「設定 InnoDB 緩衝池預取 (預讀)」。
InnoDB
標準監視器輸出在 BUFFER POOL AND MEMORY
區段中包含數個關於緩衝池 LRU 演算法運作的欄位。如需詳細資訊,請參閱使用 InnoDB 標準監視器監視緩衝池。
您可以設定緩衝池的各個方面以改善效能。
理想情況下,您可以將緩衝池的大小設定為實際可行的最大值,並為伺服器上的其他程序保留足夠的記憶體,使其不會發生過度的分頁。緩衝池越大,
InnoDB
就越像記憶體內資料庫,從磁碟讀取資料一次,然後在後續讀取期間從記憶體存取資料。請參閱第 17.8.3.1 節「設定 InnoDB 緩衝池大小」。在具有足夠記憶體的 64 位元系統上,您可以將緩衝池分割成多個部分,以盡量減少並行作業之間對記憶體結構的競爭。如需詳細資訊,請參閱第 17.8.3.2 節「設定多個緩衝池執行個體」。
您可以將頻繁存取的資料保留在記憶體中,而不受會將大量不常存取資料帶入緩衝池的作業突然激增的影響。如需詳細資訊,請參閱第 17.8.3.3 節「使緩衝池具有掃描抵抗能力」。
您可以控制如何以及何時執行預讀請求,以非同步方式將頁面預先提取到緩衝池中,以預期即將發生的需求。如需詳細資訊,請參閱第 17.8.3.4 節「設定 InnoDB 緩衝池預取 (預讀)」。
您可以控制何時發生背景清除,以及清除速率是否根據工作負載動態調整。如需詳細資訊,請參閱第 17.8.3.5 節「設定緩衝池清除」。
您可以設定
InnoDB
如何保留目前的緩衝池狀態,以避免在伺服器重新啟動後出現長時間的暖機期。如需詳細資訊,請參閱第 17.8.3.6 節「儲存與還原緩衝池狀態」。
InnoDB
標準監視器輸出 (可以使用SHOW ENGINE INNODB STATUS
存取) 提供關於緩衝池運作的指標。緩衝池指標位於 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
標準監視器輸出以來經過的時間為基礎。
表 17.2 InnoDB 緩衝池指標
名稱 | 說明 |
---|---|
配置的記憶體總量 | 以位元組為單位,為緩衝池配置的總記憶體。 |
配置的字典記憶體 | 以位元組為單位,為 InnoDB 資料字典配置的總記憶體。 |
緩衝池大小 | 配置給緩衝池的總頁面大小。 |
可用緩衝區 | 緩衝池可用列表的總頁面大小。 |
資料庫頁面 | 緩衝池 LRU 列表的總頁面大小。 |
舊資料庫頁面 | 緩衝池舊 LRU 子列表的總頁面大小。 |
修改過的資料庫頁面 | 緩衝池中目前修改過的頁面數量。 |
待處理的讀取 | 等待讀取到緩衝池中的緩衝池頁面數量。 |
待處理的寫入 LRU | 緩衝池中要從 LRU 列表底部寫出的舊髒頁面數量。 |
待處理的寫入清除列表 | 在檢查點期間要清除的緩衝池頁面數量。 |
待處理的單頁寫入 | 緩衝池中待處理的獨立頁面寫入數量。 |
變年輕的頁面 | 在緩衝池 LRU 列表中變年輕 (移至「新」頁面子列表的頭部) 的總頁面數量。 |
沒有變年輕的頁面 | 在緩衝池 LRU 列表中沒有變年輕 (一直保留在「舊」子列表中而沒有變年輕) 的總頁面數量。 |
youngs/s | 每秒平均值,表示在緩衝池 LRU 列表中存取舊頁面,導致頁面變年輕。如需更多資訊,請參閱此表格後面的註解。 |
non-youngs/s | 每秒平均值,表示在緩衝池 LRU 列表中存取舊頁面,導致頁面沒有變年輕。如需更多資訊,請參閱此表格後面的註解。 |
讀取的頁面 | 從緩衝池讀取的總頁面數。 |
建立的頁面 | 在緩衝池中建立的總頁面數。 |
寫入的頁面 | 從緩衝池寫出的總頁面數。 |
reads/s | 每秒平均緩衝池頁面讀取數。 |
creates/s | 每秒平均緩衝池頁面建立數。 |
writes/s | 每秒平均緩衝池頁面寫入數。 |
緩衝池命中率 | 從緩衝池讀取的頁面相較於從磁碟儲存讀取的頁面的緩衝池頁面命中率。 |
變年輕的速率 | 頁面存取導致頁面變年輕的平均命中率。如需更多資訊,請參閱此表格後面的註解。 |
未變年輕的速率 | 頁面存取沒有導致頁面變年輕的平均命中率。如需更多資訊,請參閱此表格後面的註解。 |
預讀的頁面 | 每秒平均預讀作業數。 |
未經存取而逐出的頁面 | 每秒平均從緩衝池逐出且未經存取的頁面數。 |
隨機預讀 | 每秒平均隨機預讀作業數。 |
LRU 長度 | 緩衝池 LRU 列表的總頁面大小。 |
unzip_LRU 長度 | 緩衝池 unzip_LRU 列表的長度 (以頁面為單位)。 |
I/O 總和 | 已存取的緩衝池 LRU 列表頁面總數。 |
I/O 目前值 | 在目前間隔中已存取的緩衝池 LRU 列表頁面總數。 |
I/O 解壓縮總和 | 已解壓縮的緩衝池 unzip_LRU 列表頁面總數。 |
I/O 解壓縮目前值 | 在目前間隔中已解壓縮的緩衝池 unzip_LRU 列表頁面總數。 |
註解:
youngs/s
指標僅適用於舊頁面。它以頁面存取次數為基礎。給定頁面可能有多個存取,所有存取都會被計算在內。如果您在沒有發生大型掃描時看到非常低的youngs/s
值,請考慮減少延遲時間,或增加用於舊子列表的緩衝池百分比。增加百分比會使舊子列表變大,因此該子列表中的頁面需要較長時間才會移動到尾部,這會增加這些頁面再次被存取並變年輕的可能性。請參閱第 17.8.3.3 節「使緩衝池具有掃描抵抗能力」。non-youngs/s
指標僅適用於舊頁面。它以頁面存取次數為基礎。給定頁面可能有多個存取,所有存取都會被計算在內。如果您在執行大型資料表掃描時沒有看到較高的non-youngs/s
值 (以及較高的youngs/s
值),請增加延遲值。請參閱第 17.8.3.3 節「使緩衝池具有掃描抵抗能力」。young-making
率計算所有緩衝池頁面的存取,而不僅僅是舊子清單中頁面的存取。young-making
率和not
率通常加總不會等於整體緩衝池的命中率。舊子清單中的頁面命中會導致頁面移至新子清單,但新子清單中的頁面命中只有在它們距離清單頭部一定距離時,才會導致頁面移至清單頭部。not (young-making rate)
是平均命中率,表示頁面存取由於未滿足innodb_old_blocks_time
定義的延遲,或由於新子清單中的頁面命中未導致頁面移至頭部,而未使頁面變年輕。此比率計算所有緩衝池頁面的存取,而不僅僅是舊子清單中頁面的存取。
緩衝池的伺服器狀態變數和 INNODB_BUFFER_POOL_STATS
表提供了許多與 InnoDB
標準監視器輸出中相同的緩衝池指標。有關更多資訊,請參閱範例 17.10,“查詢 INNODB_BUFFER_POOL_STATS 表”。