MySQL InnoDB緩衝池

eric0435發表於2022-03-17

InnoDB緩衝池
InnoDB維護一個稱為緩衝池的儲存區域,用於在記憶體中快取資料和索引。瞭解InnoDB緩衝池是如何工作的,並利用它將頻繁訪問的資料儲存在記憶體中,這是MySQL調優的一個重要方面。

您可以配置InnoDB緩衝池的各個方面來提高效能:
.理想情況下,您可以將緩衝池的大小設定為與實際情況一樣大的值,從而為伺服器上的其他程式留下足夠的記憶體以執行,而不會造成過多的分頁。緩衝池越大,InnoDB的行為就越像記憶體中的資料庫,從磁碟讀取資料一次,然後在後續讀取時訪問記憶體中的資料。

.對於具有大記憶體大小的64位系統,可以將緩衝池分成多個部分,以最小化併發操作之間對記憶體結構的爭用。

.您可以將頻繁訪問的資料儲存在記憶體中,雖然備份或報告等操作的活動突然出現峰值

.您可以控制InnoDB何時以及如何執行預讀請求,以非同步的方式將頁面預取到緩衝池中,預期這些頁面很快就會被需要

.您可以控制髒頁面何時發生後臺重新整理,以及InnoDB是否根據工作負載動態調整重新整理速率

.您可以對InnoDB緩衝池重新整理行為進行微調,以提高效能

.您可以配置InnoDB如何儲存當前的緩衝池狀態,以避免伺服器重啟後的長時間預熱。您還可以在伺服器執行時儲存當前緩衝池狀態

InnoDB緩衝池LRU演算法
InnoDB以列表的形式管理緩衝池,使用最近最少使用(LRU)演算法的變體。當需要空間向池中新增一個新頁面時,InnoDB會刪除最近使用最少的頁面,並將新頁面新增到列表的中間。這個中點插入策略將列表視為兩個子列表:
.頂部是最近訪問的新(或年輕)頁面的子列表
.在尾部,是最近訪問較少的舊頁面的子列表。

這種演算法將查詢大量使用的頁面保留在新的子列表中。舊的子列表包含較少使用的頁面;這些頁面可能會被驅逐。

預設情況下,LRU演算法的操作如下:
.3/8的緩衝池用於舊的子列表。

.列表的中點是新子列表的尾部與舊子列表的頭部的邊界

.當InnoDB將一個頁面讀入緩衝池時,它最初會將頁面插入到中點(舊子列表的頭部)。可以讀入一個頁面,因為它是使用者指定操作(如SQL查詢)所需要的,或者是InnoDB自動執行的預讀操作的一部分

.訪問舊子列表中的頁面會使其年輕,將其移動到緩衝池的頭部(新子列表的頭部)。如果因為需要而讀入該頁,則立即進行第一次訪問,並使該頁年輕。如果由於預讀而讀入該頁,則不會立即進行第一次訪問(可能在該頁被驅逐之前根本不會進行第一次訪問)。

.在資料庫操作時,緩衝池中未被訪問的頁面會向列表的尾部移動。新子列表和舊子列表中的頁面都會隨著其他頁面的更新而老化。舊子列表中的頁面也隨著頁面插入到中點而老化。最終,長時間未使用的頁面會到達舊的子列表的尾部並被移除。

.預設情況下,透過查詢讀取的頁面會立即移動到新的子列表中,這意味著它們在緩衝池中停留的時間更長。一個表掃描(如mysqldump操作,或沒有WHERE子句的SELECT語句)可以將大量資料引入緩衝池,並驅逐等量的舊資料,即使新資料永遠不會再次使用。類似地,由預讀後臺執行緒載入並只訪問一次的頁面將移到新列表的頭部。這些情況會將經常使用的頁面推到舊的子列表中,在那裡它們會被清除

InnoDB Standard Monitor輸出包含了BUFFER POOL AND MEMORY部分的幾個欄位,這些欄位與緩衝池LRU演算法的操作有關。

InnoDB緩衝池配置選項
有幾個配置選項會影響InnoDB緩衝池的不同方面。
.innodb_buffer_pool_size
指定緩衝池的大小。如果緩衝池很小,而您有足夠的記憶體,那麼擴大緩衝池可以透過減少在查詢訪問InnoDB表時所需的磁碟I/O數量來提高效能。innodb_buffer_pool_size選項是動態的,它允許您在不重啟伺服器的情況下配置緩衝池大小

.innodb_buffer_pool_chunk_size
定義InnoDB緩衝池調整操作的塊大小。

.innodb_buffer_pool_instances
將緩衝池劃分為使用者指定數量的獨立區域,每個區域都有自己的LRU列表和相關的資料結構,以減少併發記憶體讀寫操作期間的爭用。只有將innodb_buffer_pool_size設定為1GB或更大時,該選項才會生效。指定的總大小將分配到所有緩衝池。為了獲得最佳效率,指定innodb_buffer_pool_instances和innodb_buffer_pool_size的組合,以便每個緩衝池例項至少為1GB。

.innodb_old_blocks_pct
指定InnoDB用於舊塊子列表的緩衝池的大約百分比。取值範圍為5 ~ 95。預設值是37(即池的3/8)。

.innodb_old_blockts_time
指定插入舊子列表的頁面在第一次訪問後必須停留在舊子列表中的時間(以毫秒為單位),然後才能移動到新子列表。如果該值為0,則插入到舊子列表中的頁面在第一次被訪問時將立即移動到新子列表中,無論插入後多久發生訪問。如果該值大於0,頁面將保留在舊的子列表中,直到在第一次訪問之後至少那麼多毫秒才會發生訪問。例如,值為1000會導致頁面在第一次訪問後在舊的子列表中停留1秒,然後才有資格移動到新的子列表。

設定innodb_old_blocks_time大於0可以防止一次性表掃描僅用於掃描的頁面淹沒新子列表。為了掃描而讀入的頁中的行將被快速連續多次訪問,但之後該頁就不再使用了。如果innodb_old_blocks_time設定為大於處理頁面所需時間的值,那麼頁面將保留在舊的子列表中,並且會被老化到列表的尾部,以便快速被移除。這樣,只用於一次性掃描的頁面不會損害新子列表中大量使用的頁面。

innodb_old_blocks_time可以在執行時設定,因此可以在執行表掃描和轉儲等操作時臨時更改:

SET GLOBAL innodb_old_blocks_time = 1000;
... perform queries that scan tables ...
SET GLOBAL innodb_old_blocks_time = 0;

如果您的目的是用表的內容填充緩衝池,則不適用此策略。例如,基準測試通常在伺服器啟動時執行表或索引掃描,因為資料在正常使用一段時間後通常會在緩衝池中。在這種情況下,讓innodb_old_blocks_time設定為0,至少在預熱階段完成之前。

.innodb_read_ahead_threshold
控制InnoDB用於將頁面預取到緩衝池中的線性預讀的靈敏度。

.innodb_random_read_ahead
啟用隨機預讀技術,將頁面預取到緩衝池中。隨機預讀是一種技術,它可以根據緩衝池中已經存在的頁面預測何時可能需要頁面,而不管這些頁面的讀取順序如何。Innodb_random_read_ahead預設禁用。

.innodb_adaptive_flushing_lwm
低水位標誌表示啟用自適應重新整理的重做日誌容量的百分比

.innodb_flush_nei***ors
指定從緩衝池重新整理頁是否也會重新整理同一區段中的其他髒頁

.innodb_flushing_avg_loops
InnoDB保持先前計算的重新整理狀態快照的迭代次數,控制自適應重新整理響應不斷變化的工作負載的速度。

.innodb_lru_scan_depth
影響緩衝池重新整理操作的演算法和啟發式演算法的引數。主要用於調優I/ o密集型工作負載的效能專家。它指定,每個緩衝池例項,緩衝池LRU列出的page_cleaner執行緒掃描在多遠的位置尋找要重新整理的髒頁。

.innodb_max_dirty_pages_pct
InnoDB會嘗試從緩衝池中重新整理資料,這樣髒頁的百分比就不會超過這個值。請指定範圍為0 ~ 99的整數。預設值為75。

.innodb_max_dirty_pages_pct_lwm
低水位標記表示啟用預沖洗的髒頁的百分比,以控制髒頁比率。預設值0完全禁用預重新整理行為

.innodb_buffer_pool_filename
指定儲存innodb_buffer_pool_dump_at_shutdown或innodb_buffer_pool_dump_now生成的表空間id和頁id列表的檔名稱。

.innodb_buffer_pool_dump_at_shutdown
指定MySQL伺服器關閉時是否記錄緩衝池中快取的頁面,以縮短下次重啟時的預熱過程

.innodb_buffer_pool_load_at_startup
指定在MySQL伺服器啟動時,緩衝池透過載入它以前持有的相同頁面自動升溫。通常與innodb_buffer_pool_dump_at_shutdown一起使用。

.innodb_buffer_pool_dump_now
立即記錄緩衝池中快取的頁面

.innodb_buffer_pool_load_now
透過載入一組資料頁,無需等待伺服器重新啟動,即可立即預熱緩衝池。對於在基準測試期間將快取記憶體恢復到已知狀態,或者在執行報告或維護查詢後讓MySQL伺服器恢復正常工作負載,都是很有用的。通常與innodb_buffer_pool_dump_now一起使用。

.innodb_buffer_pool_dump_pct
指定每個緩衝池要讀出和轉儲的最近使用的頁的百分比。取值範圍是1 ~ 100。

.innodb_buffer_pool_load_abort
中斷innodb_buffer_pool_load_at_startup或innodb_buffer_pool_load_now觸發的緩衝區內容恢復過程。

配置InnodDB Buffer Pool大小
您可以在伺服器執行時離線(啟動時)或線上配置InnoDB緩衝池大小

增加或減少innodb_buffer_pool_size時,以塊為單位進行操作。Chunk大小是由innodb_buffer_pool_chunk_size配置選項定義的,預設值是128M。

緩衝池大小必須等於或等於innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍數。如果innodb_buffer_pool_size的值不等於或不等於innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍數,緩衝池大小會自動調整為innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍數或等於不小於指定的緩衝池大小。

在下面的例子中,innodb_buffer_pool_size設定為4G, innodb_buffer_pool_instances設定為8。innodb_buffer_pool_chunk_size為預設值128M。

4G是有效的innodb_buffer_pool_size值,因為8G是innodb_buffer_pool_instances=8 * innodb_buffer_pool_chunk_size=128M的倍數,即1G。

[mysql@localhost mysql]$ mysqld --innodb_buffer_pool_size=4G --innodb_buffer_pool_instances=8
[mysql@localhost ~]$ mysql -uroot -pxxzx7817600
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SELECT @@innodb_buffer_pool_size/1024/1024/1024;
+------------------------------------------+
| @@innodb_buffer_pool_size/1024/1024/1024 |
+------------------------------------------+
|                           4.000000000000 |
+------------------------------------------+
1 row in set (0.00 sec)

本例中,innodb_buffer_pool_size設定為3G, innodb_buffer_pool_instances設定為16。innodb_buffer_pool_chunk_size為預設值128M。在這種情況下,9G不是innodb_buffer_pool_instances= 16 * innodb_buffer_pool_chunk_size = 128M的倍數,所以透過innodb_buffer_pool_size調整為4G,這是下一個的倍數innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances不小於指定的緩衝池大小。

[mysql@localhost mysql]$ mysqld --innodb_buffer_pool_size=3G --innodb_buffer_pool_instances=16
[mysql@localhost ~]$ mysql -uroot -pxxzx7817600
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SELECT @@innodb_buffer_pool_size/1024/1024/1024;
+------------------------------------------+
| @@innodb_buffer_pool_size/1024/1024/1024 |
+------------------------------------------+
|                           4.000000000000 |
+------------------------------------------+
1 row in set (0.00 sec)

配置InnoDB Buffer Pool Chunk大小
innodb_buffer_pool_chunk_size可以以1MB(1048576位元組)為單位增加或減少,但只能在啟動時修改,在命令列字串或MySQL配置檔案中。

命令列設定如下:

mysqld --innodb_buffer_pool_chunk_size=134217728
配置檔案設定如下:
[mysqld]
innodb_buffer_pool_chunk_size=134217728

當修改innodb_buffer_pool_chunk_size時適用以下條件:
.如果新innodb_buffer_pool_chunk_size值乘以innodb_buffer_pool_instances比當前的buffer pool大小大。innodb_buffer_pool_chunk_size被截斷為innodb_buffer_pool_size/innodb_buffer_pool_instances

例如,如果buffer pool的初始大小為2GB,4個buffer pool instances和chunk size為1GB,那麼chunk size會被截斷為innodb_buffer_pool_size/innodb_buffer_pool_instances值:

[mysql@localhost ~]$ mysqld --innodb_buffer_pool_size=2147483648 --innodb_buffer_pool_instances=4 --innodb_buffer_pool_chunk_size=1073741824;
[mysql@localhost ~]$ mysql -uroot -pxxzx7817600 mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.26-log Source distribution
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SELECT @@innodb_buffer_pool_size;
+---------------------------+
| @@innodb_buffer_pool_size |
+---------------------------+
|                2147483648 |
+---------------------------+
1 row in set (0.00 sec)
mysql> SELECT @@innodb_buffer_pool_instances;
+--------------------------------+
| @@innodb_buffer_pool_instances |
+--------------------------------+
|                              4 |
+--------------------------------+
1 row in set (0.00 sec)
#Chunk size was set to 1GB (1073741824 bytes) on startup but was truncated to innodb_buffer_pool_size / innodb_buffer_pool_instances
mysql> SELECT @@innodb_buffer_pool_chunk_size;
+---------------------------------+
| @@innodb_buffer_pool_chunk_size |
+---------------------------------+
|                       536870912 |
+---------------------------------+
1 row in set (0.00 sec)

.buffer pool的大小必須總是等於或是innodb_buffer_pool_chunk_size*innodb_buffer_pool_instances的倍數。如果你修改innodb_buffer_pool_chunk_size,那麼innodb_buffer_pool_size會被自動調整為等於或是innodb_buffer_pool_chunk_size*innodb_buffer_pool_instances的倍數,並且不會小於當前的buffer pool大小。當buffer pool被初始化時進行調理。下面演示這個例子:

# The buffer pool has a default size of 128MB (134217728 bytes)
mysql> SELECT @@innodb_buffer_pool_size;
+---------------------------+
| @@innodb_buffer_pool_size |
+---------------------------+
|                 134217728 |
+---------------------------+
1 row in set (0.00 sec)
# The chunk size is also 128MB (134217728 bytes)
mysql> SELECT @@innodb_buffer_pool_chunk_size;
+---------------------------------+
| @@innodb_buffer_pool_chunk_size |
+---------------------------------+
|                       134217728 |
+---------------------------------+
1 row in set (0.00 sec)
# There is a single buffer pool instance
mysql> SELECT @@innodb_buffer_pool_instances;
+--------------------------------+
| @@innodb_buffer_pool_instances |
+--------------------------------+
|                              1 |
+--------------------------------+
1 row in set (0.00 sec)
# Chunk size is decreased by 1MB (1048576 bytes) at startup  (134217728 - 1048576 = 133169152):
[mysql@localhost ~]$ mysqld --innodb_buffer_pool_chunk_size=133169152
mysql> SELECT @@innodb_buffer_pool_chunk_size;
+---------------------------------+
| @@innodb_buffer_pool_chunk_size |
+---------------------------------+
|                       133169152 |
+---------------------------------+
1 row in set (0.00 sec)
# Buffer pool size increases from 134217728 to 266338304
# Buffer pool size is automatically adjusted to a value that is equal to
# or a multiple of innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances
# that is not less than current buffer pool size
mysql> SELECT @@innodb_buffer_pool_size;
+---------------------------+
| @@innodb_buffer_pool_size |
+---------------------------+
|                 266338304 |
+---------------------------+
1 row in set (0.00 sec)

下面使用多個buffer pool instances來演示這種行為:

# The buffer pool has a default size of 2GB (2147483648 bytes)
mysql> SELECT @@innodb_buffer_pool_size;
+---------------------------+
| @@innodb_buffer_pool_size |
+---------------------------+
|                2147483648 |
+---------------------------+
1 row in set (0.01 sec)
# The chunk size is .5 GB (536870912 bytes)
mysql> SELECT @@innodb_buffer_pool_chunk_size;
+---------------------------------+
| @@innodb_buffer_pool_chunk_size |
+---------------------------------+
|                       536870912 |
+---------------------------------+
1 row in set (0.00 sec)
# There are 4 buffer pool instances
mysql> SELECT @@innodb_buffer_pool_instances;
+--------------------------------+
| @@innodb_buffer_pool_instances |
+--------------------------------+
|                              4 |
+--------------------------------+
1 row in set (0.00 sec)
# Chunk size is decreased by 1MB (1048576 bytes) at startup (536870912 - 1048576 = 535822336):
[root@localhost ~]# mysqld --innodb_buffer_pool_size=2147483648 --innodb_buffer_pool_instances=4 --innodb_buffer_pool_chunk_size=535822336
mysql> SELECT @@innodb_buffer_pool_chunk_size;
+---------------------------------+
| @@innodb_buffer_pool_chunk_size |
+---------------------------------+
|                       535822336 |
+---------------------------------+
1 row in set (0.00 sec)
# Buffer pool size increases from 2147483648 to 4286578688
# Buffer pool size is automatically adjusted to a value that is equal to
# or a multiple of innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances
# that is not less than current buffer pool size of 2147483648
mysql> SELECT @@innodb_buffer_pool_size;
+---------------------------+
| @@innodb_buffer_pool_size |
+---------------------------+
|                4286578688 |
+---------------------------+
1 row in set (0.00 sec)

當改變innodb_buffer_pool_chunk_size的大小時應該要小心仔細,因為改變這個值可能會增加buffer pool的大小,比如上面的兩個示例。在改變innodb_buffer_pool_chunk_size之前,需要計算對innodb_buffer_pool_size的影響確保對buffer pool的改變結果可以接受。

注意:為了避免潛在的效能問題,chunk的數量(innodb_buffer_pool_size/innodb_buffer_pool_chunk_size)不應該超過1000。

聯機配置InnoDB Buffer Pool大小
innodb_buffer_pool_size配置選項也可以使用set語句來進行動態設定,在不重啟伺服器的情況下來重置buffer pool的大小。例如:

mysql> set global innodb_buffer_pool_size=402653184;
Query OK, 0 rows affected (0.00 sec)

透過InnoDB APIs執行的活動事務與操作應該在重置buffer pool大小之前完成執行。當初始化重置操作時,直到所有活動的事務完成之前重置操作不會啟動。一旦重置操作正在執行時,直到重置操作完成之前請求訪問buffer pool的新事務與操作必須等待。這個規則的例外是,當緩衝池的大小減小並且頁面被撤銷時,允許對緩衝池進行併發訪問。允許併發訪問的一個缺點是,當頁面被撤銷時,它可能會導致可用頁面的臨時短缺。

監控聯機buffer pool重置程式

innodb_buffer_pool_resize_status用於報告buffer pool重置程式。例如:
mysql> SHOW STATUS WHERE Variable_name='InnoDB_buffer_pool_resize_status';
+----------------------------------+----------------------------------------------------+
| Variable_name                    | Value                                              |
+----------------------------------+----------------------------------------------------+
| Innodb_buffer_pool_resize_status | Completed resizing buffer pool at 220120 11:13:11. |
+----------------------------------+----------------------------------------------------+
1 row in set (0.04 sec)

buffer pool重置程式也會被記錄到伺服器錯誤日誌中。上面的例子當增加buffer pool大小時日誌資訊如下:

2022-01-20T03:13:11.574147Z 0 [Note] InnoDB: Resizing buffer pool from 134217728 to 402653184 (unit=134217728).
2022-01-20T03:13:11.574149Z 2 [Note] InnoDB: Requested to resize buffer pool. (new size: 402653184 bytes)
2022-01-20T03:13:11.574320Z 0 [Note] InnoDB: Disabling adaptive hash index.
2022-01-20T03:13:11.600728Z 0 [Note] InnoDB: disabled adaptive hash index.
2022-01-20T03:13:11.600820Z 0 [Note] InnoDB: Withdrawing blocks to be shrunken.
2022-01-20T03:13:11.611701Z 0 [Note] InnoDB: Latching whole of buffer pool.
2022-01-20T03:13:11.611904Z 0 [Note] InnoDB: buffer pool 0 : resizing with chunks 1 to 3.
2022-01-20T03:13:11.652012Z 0 [Note] InnoDB: buffer pool 0 : 2 chunks (16384 blocks) were added.
2022-01-20T03:13:11.652085Z 0 [Note] InnoDB: Resizing hash tables.
2022-01-20T03:13:11.653337Z 0 [Note] InnoDB: buffer pool 0 : hash tables were resized.
2022-01-20T03:13:11.653413Z 0 [Note] InnoDB: Resizing also other hash tables.
2022-01-20T03:13:11.665535Z 0 [Note] InnoDB: Resized hash tables at lock_sys, adaptive hash index, dictionary.
2022-01-20T03:13:11.665594Z 0 [Note] InnoDB: Completed to resize buffer pool from 134217728 to 402653184.
2022-01-20T03:13:11.665626Z 0 [Note] InnoDB: Re-enabled adaptive hash index.
2022-01-20T03:13:11.665662Z 0 [Note] InnoDB: Completed resizing buffer pool at 220120 11:13:11.

下面顯示了當減少buffer pool大小的日誌資訊如下:

mysql> set global innodb_buffer_pool_size=209715200;
Query OK, 0 rows affected, 1 warning (0.01 sec)
2022-01-20T03:25:22.635263Z 0 [Note] InnoDB: Resizing buffer pool from 402653184 to 268435456 (unit=134217728).
2022-01-20T03:25:22.635442Z 0 [Note] InnoDB: Disabling adaptive hash index.
2022-01-20T03:25:22.639442Z 0 [Note] InnoDB: disabled adaptive hash index.
2022-01-20T03:25:22.639531Z 0 [Note] InnoDB: Withdrawing blocks to be shrunken.
2022-01-20T03:25:22.639581Z 0 [Note] InnoDB: buffer pool 0 : start to withdraw the last 8192 blocks.
2022-01-20T03:25:22.642058Z 0 [Note] InnoDB: buffer pool 0 : withdrawing blocks. (8192/8192)
2022-01-20T03:25:22.642104Z 0 [Note] InnoDB: buffer pool 0 : withdrew 8192 blocks from free list. Tried to relocate 0 pages (8192/8192).
2022-01-20T03:25:22.642168Z 0 [Note] InnoDB: buffer pool 0 : withdrawn target 8192 blocks.
2022-01-20T03:25:22.642206Z 0 [Note] InnoDB: Latching whole of buffer pool.
2022-01-20T03:25:22.642260Z 0 [Note] InnoDB: buffer pool 0 : resizing with chunks 3 to 2.
2022-01-20T03:25:22.645518Z 0 [Note] InnoDB: buffer pool 0 : 1 chunks (8192 blocks) were freed.
2022-01-20T03:25:22.645577Z 0 [Note] InnoDB: Completed to resize buffer pool from 402653184 to 268435456.
2022-01-20T03:25:22.645612Z 0 [Note] InnoDB: Re-enabled adaptive hash index.
2022-01-20T03:25:22.645660Z 0 [Note] InnoDB: Completed resizing buffer pool at 220120 11:25:22.

聯機buffer pool重置內部構件
重置操作是由一個後臺執行緒執行的。當增加buffer pool的大小時,重置操作執行以下操作:
.向chunks中新增頁(chunk大小由innodb_buffer_pool_chunk_size決定)

.轉換雜湊表,列表和指標來使用記憶體中的新地址

.向可用列表中增加新的記憶體頁

當這些操作正在處理時,訪問buffer pool的其它執行緒會被阻塞。

當減小buffer pool的大小時,重置操作執行以下操作:
.對buffer pool進行碎片整理並回收記憶體頁
.刪除chunks中的記憶體頁(chunk大小由innodb_buffer_pool_chunk_size決定)
.轉換雜湊表,列表和指標來使用記憶體中的新地址

在這些操作中,只有對緩衝池進行碎片整理和收回頁面才允許其他執行緒併發地訪問緩衝池

配置多個buffer pool例項
對於緩衝池在幾GB範圍內的系統,透過減少不同執行緒讀寫快取頁面時的爭用,將緩衝池劃分為單獨的例項可以提高併發性。這個特性通常適用於緩衝池大小在幾GB範圍內的系統。使用innodb_buffer_pool_instances配置選項配置多個緩衝池例項,您還可以調整innodb_buffer_pool_size值。

當InnoDB緩衝池很大時,很多資料請求可以透過從記憶體中獲取來滿足。您可能會遇到來自多個試圖同時訪問緩衝池的執行緒的瓶頸。您可以啟用多個緩衝池來最小化此爭用。使用雜湊函式,將儲存在緩衝池或從緩衝池讀取的每個頁面隨機分配給其中一個緩衝池。每個緩衝池管理自己的空閒列表,重新整理列表,lru和所有其他連線到緩衝池的資料結構,並由自己的緩衝池互斥保護。

要啟用多個緩衝池例項,將innodb_buffer_pool_instances配置選項設定為大於1(預設)的值,最大64(最大值)。只有當innodb_buffer_pool_size大於等於1GB時,該選項才會生效。指定的總大小在所有緩衝池中進行分配。為了獲得最佳效率,請指定
innodb_buffer_pool_instances和innodb_buffer_pool_size的組合,以便每個緩衝池例項至少為1GB。

Making the Buffer Pool Scan Resistant
InnoDB沒有使用嚴格的LRU演算法,而是使用了一種技術來最小化被帶入緩衝池並且不再被訪問的資料量。這樣做的目的是確保頻繁訪問(熱)的頁面保持在緩衝池中,即使預讀和全表掃描會帶來新的塊,這些塊之後可能會被訪問,也可能不會被訪問。

新讀的塊被插入到LRU列表的中間。所有新讀的頁面被插入到一個位置,預設是3/8從LRU列表的尾部。當在緩衝池中第一次訪問這些頁面時,它們被移動到列表的前面(最近使用的端)。因此,那些從未被訪問過的頁面永遠不會出現在LRU列表的前面,並且會比嚴格的LRU方法更早老化。這種安排將LRU列表分為兩個段,其中插入點下游的頁面被認為是舊的,是LRU驅逐的理想物件

你可以控制LRU列表中的插入點,並選擇InnoDB是否對透過表掃描或索引掃描進入緩衝池的塊應用相同的最佳化。配置引數innodb_old_blocks_pct控制LRU列表中舊塊的百分比。innodb_old_blocks_pct預設值為37,對應原來的3/8固定比例。取值範圍是5(緩衝池中的新頁面會很快老化)到95(只有5%的緩衝池被預留給熱頁面,這使得演算法接近於我們熟悉的LRU策略)。

使緩衝池不因預讀而被攪動的最佳化可以避免由於表或索引掃描而出現的類似問題。在這些掃描中,一個資料頁面通常會被快速連續地訪問幾次,並且再也不會被碰觸。innodb_old_blocks_time配置引數指定了頁面在第一次訪問後,該頁面可以被訪問且不被移動到LRU列表的前面(最近使用的端)的時間視窗(以毫秒為單位)。innodb_old_blocks_time預設值為1000。增加這個值會使越來越多的塊從緩衝池中更快地老化。

innodb_old_blocks_pct和innodb_old_blocks_time都是動態的,全域性的,可以在MySQL選項檔案(my.cnf或my.ini)中指定,或者在執行時用SET global命令更改。更改設定需要超級許可權。

為了幫助您評估設定這些引數的效果,可以使用SHOW ENGINE INNODB STATUS命令報告緩衝池統計資訊

由於這些引數的影響可能會根據硬體配置、資料和工作負載的細節發生很大的變化,所以在任何對效能至關重要的環境或生產環境中更改這些設定之前,始終要進行基準測試來驗證其有效性。

在混合的工作負載中,大多數活動是OLTP型別和週期性的批次報告查詢,導致大的掃描,設定innodb_old_blocks_time的值在批次執行期間可以幫助保持正常工作負載的工作集在緩衝池中。

當掃描的大表不能完全放入緩衝池時,將innodb_old_blocks_pct設定為一個小值,可以使只讀取一次的資料不會佔用緩衝池的很大一部分。例如,設定innodb_old_blocks_pct=5可以將只讀取一次的資料限制為緩衝池的5%。

當掃描適合記憶體的小表時,在緩衝池中移動頁面的開銷更小,所以你可以保留innodb_old_blocks_pct的預設值,甚至更高,比如innodb_old_blocks_pct=50。

innodb_old_blocks_time引數的效果比innodb_old_blocks_pct引數更難預測,innodb_old_blocks_pct引數相對較小,並且隨著工作負載的變化而變化。如果透過調整innodb_old_blocks_pct提高的效能還不夠,那麼可以進行自己的基準測試,以獲得最佳值。

配置InnoDB緩衝池預取(預讀)
預讀請求是一個I/O請求,在緩衝池中非同步預取多個頁面,預計這些頁面很快就會被需要。請求把一個extent內所有頁面讀取緩衝池。InnoDB使用兩種預讀演算法來提高I/O效能:線性預讀是一種技術,它可以根據緩衝池中被順序訪問的頁面來預測哪些頁面可能很快會被需要。你可以使用配置引數innodb_read_ahead_threshold,透過調整觸發非同步讀請求所需的連續頁面訪問次數來控制InnoDB何時執行預讀操作。在新增這個引數之前,InnoDB只會在讀取當前extent的最後一頁時,計算是否對整個下一個區段發出非同步預取請求。

配置引數innodb_read_ahead_threshold控制InnoDB在檢測順序頁面訪問模式時的敏感度。如果從一個區順序讀取的頁面數大於或等於innodb_read_ahead_threshold, InnoDB會啟動一個後續整個區的非同步預讀操作。Innodb_read_ahead_threshold可以設定為0-64之間的任意值。預設值是56。值越高,表示訪問模式檢查越嚴格。例如,如果您將該值設定為48,則只有在當前區段中連續訪問了48個頁面時,InnoDB才會觸發一個線性預讀請求。如果該值為8,InnoDB即使在區段中只有8個頁面被順序訪問也會觸發非同步提前讀。您可以在MySQL配置檔案中設定該引數的值,或者使用set GLOBAL命令動態更改它,該命令需要超級許可權。

隨機預讀是一種根據緩衝池中已經存在的頁面來預測何時可能很快需要這些頁面,而不考慮這些頁面被讀取的順序的一種技術。如果在緩衝池中發現了來自同一區段的連續13個頁面,InnoDB會非同步發出一個請求來預取區段的剩餘頁面。要啟用此特性,請將配置變數
innodb_random_read_ahead設定為ON。

SHOW ENGINE INNODB STATUS命令用來檢視相關統計資訊,以幫助您評估預讀演算法的有效性。統計資訊包括以下全域性狀態變數的計數器資訊

 Innodb_buffer_pool_read_ahead
 Innodb_buffer_pool_read_ahead_evicted
 Innodb_buffer_pool_read_ahead_rnd

這些資訊在微調innodb_random_read_ahead設定時非常有用

配置InnoDB緩衝池重新整理
InnoDB在後臺執行一些任務,包括從緩衝池重新整理髒頁(那些已經更改但還沒有寫入資料庫檔案的頁)。

當緩衝池中髒頁的百分比達到innodb_max_dirty_pages_pct_lwm設定的低水位時,InnoDB開始重新整理緩衝池頁面。這個選項的目的是控制緩衝池中髒頁的比例,並在理想情況下防止髒頁的百分比達到innodb_max_dirty_pages_pct。如果緩衝池中髒頁的百分比超過了innodb_max_dirty_pages_pct, InnoDB就會開始主動重新整理緩衝池頁面。

InnoDB會根據重做日誌的生成速度和當前的重新整理速度來估算所需的重新整理速度。其目的是透過確保緩衝區重新整理活動與保持緩衝池清潔的需求保持一致,從而平滑整體效能。當過多的緩衝池重新整理限制了用於普通讀寫活動的I/O容量時,自動調整重新整理速率可以幫助避免吞吐量的突然下降

InnoDB以迴圈的方式使用它的日誌檔案。在重用日誌檔案的一部分之前,InnoDB會將包含該部分日誌的重做條目的所有髒緩衝池頁面重新整理到磁碟上,這個過程稱為尖銳檢查點(sharp checkpoint)。如果工作負載是寫密集型的,那麼它會生成大量的重做資訊,所有這些資訊都會寫入日誌檔案。如果日誌檔案中的所有可用空間都用完,就會出現一個尖銳的檢查點,導致吞吐量暫時下降。即使沒有達到innodb_max_dirty_pages_pct,這種情
況也會發生。

InnoDB使用一種基於啟發式的演算法來避免這種情況,透過測量緩衝池中髒頁的數量和重做生成的速率。根據這些資料,InnoDB決定每秒鐘從緩衝池中重新整理多少髒頁。這種自適應演算法能夠應對工作負荷的突然變化。

內部基準測試表明,該演算法不僅能在一段時間內保持吞吐量,而且還能顯著提高總體吞吐量。

因為自適應重新整理可以顯著影響工作負載的I/O模式,所以innodb_adaptive_flushing配置引數允許關閉該特性。innodb_adaptive_flushing預設值為“ON”,開啟自適應重新整理演算法。您可以在MySQL選項檔案(my.cnf或my.ini)中設定該引數的值,或者使用set GLOBAL命令動態更改它,該命令需要超級許可權。

Fine-tuning InnoDB Buffer Pool Flushing(微調InnoDB Buffer Pool Flushing)
配置選項innodb_flush_nei***ors和innodb_lru_scan_depth可以讓你最佳化InnoDB緩衝池的重新整理過程。

innodb_flush_nei***ors
指定從緩衝池重新整理頁是否也會重新整理同一區段內的其他髒頁。當表資料儲存在傳統的HDD儲存裝置上時,與在不同時間重新整理單個頁面相比,在一個操作中重新整理鄰居頁面可以減少I/O開銷(主要用於磁碟尋道操作)。對於儲存在SSD上的表資料,尋道時間不是一個重要因素,您可以禁用此設定來分散寫操作。

innodb_lru_scan_depth
指定每個緩衝池例項,在緩衝池LRU列表的最下方有多遠的頁面清理執行緒掃描要重新整理的髒頁面。這是一個每秒執行一次的後臺操作。

這些選項主要幫助編寫密集型工作負載。對於大量的DML活動,如果不夠激進,重新整理可能會落後,導致緩衝池中過多的記憶體使用;或者,如果這種機制過於激進,由重新整理引起的磁碟寫可能會使I/O容量飽和。理想的設定取決於您的工作負載、資料訪問模式和儲存配置(例如,資料是儲存在HDD還是SSD裝置上)。

對於具有持續的高負載或波動較大的負載的系統,有幾個配置選項可以讓您調整InnoDB表的重新整理行為:

innodb_adaptive_flushing_lwm
innodb_max_dirty_pages_pct_lwm
innodb_io_capacity_max
innodb_flushing_avg_loops

這些選項提供給innodb_adaptive_flushing選項使用的公式

innodb_adaptive_flushing, innodb_io_capacity和innodb_max_dirty_pages_pct選項受以下選項的限制或擴充套件

innodb_adaptive_flushing_lwm
innodb_io_capacity_max
innodb_max_dirty_pages_pct_lwm

InnoDB自適應重新整理機制並不是在所有情況下都適用。當重做日誌有被填滿的危險時,它能提供最大的好處。innodb_adaptive_flushing_lwm選項指定重做日誌容量的低水位百分比;當超過這個閾值時,即使沒有指定innodb_adaptive_flushing選項,InnoDB開啟自適應重新整理。

如果重新整理活動遠遠落後,InnoDB可以比innodb_io_capacity指定的重新整理更積極。innodb_io_capacity_max表示在這種緊急情況下使用的I/O容量上限,因此I/O峰值不會消耗伺服器的所有容量。

InnoDB會嘗試從緩衝池重新整理資料,以保證髒頁的百分比不超過innodb_max_dirty_pages_pct的值。innodb_max_dirty_pages_pct的預設值是75。

innodb_max_dirty_pages_pct設定為重新整理活動建立的一個目標。它不影響沖洗速度。

innodb_max_dirty_pages_pct_lwm選項指定了一個低水位標值,表示啟用預重新整理以控制髒頁比例的髒頁百分比,並在理想情況下防止髒頁百分比達到innodb_max_dirty_pages_pct。innodb_max_dirty_pages_pct_lwm=0的值禁用預重新整理行為。

上面提到的大多數選項最適用於長時間執行寫量大的工作負載的伺服器,並且幾乎沒有減少負載時間來趕上等待寫入磁碟的更改。

innodb_flushing_avg_loops定義了InnoDB儲存之前計算的重新整理狀態快照的迭代次數,它控制了自適應重新整理對前臺負載變化的響應速度。innodb_flushing_avg_loops設定的值越高,意味著InnoDB將保持之前計算的快照時間越長,因此自適應重新整理的響應速度會越慢。高值也會減少前臺和後臺工作之間的積極反饋,但當設定一個高值時它最重要的是要確保InnoDB重做日誌利用率不到75%(非同步重新整理的硬編碼限制開始),innodb_max_dirty_pages_pct設定使髒頁的數量水平適合工作負載。

如果系統的工作負載一致,innodb_log_file_size比較大,並且沒有達到75%的重做日誌空間利用率,那麼應該使用較高的innodb_flushing_avg_loops值來保持重新整理儘可能平滑。對於負載峰值極大的系統或日誌檔案不提供大量空間的系統,考慮使用較小的
innodb_flushing_avg_loops值。較小的值允許重新整理密切跟蹤負載,並有助於避免達到75%的重做日誌空間利用率。

儲存和恢復緩衝池狀態
為了減少伺服器重啟後的預熱時間,InnoDB在伺服器關閉時為每個緩衝池儲存最近使用的頁面的百分比,並在伺服器啟動時恢復這些頁面。最近使用的頁面的儲存百分比由innodb_buffer_pool_dump_at_shutdown配置選項定義。

重新啟動一個繁忙的伺服器後,通常會有一個預熱期,吞吐量會穩步增加,因為緩衝池中的磁碟頁會被重新放入記憶體(查詢、更新相同的資料,等等)。在啟動時恢復緩衝池的能力,透過重新載入重新啟動前緩衝池中的磁碟頁,而不是等待DML操作訪問相應的行,縮短了預熱時間。此外,I/O請求可以批次執行,使整體I/O速度更快。頁面載入發生在後臺,不會延遲資料庫啟動。

除了在關閉時儲存緩衝池狀態並在啟動時恢復它之外,您還可以在伺服器執行時的任何時候儲存和恢復緩衝池狀態。例如,在穩定的工作負載下達到穩定的吞吐量後,可以儲存緩衝池的狀態。您還可以在執行報告或維護作業之後恢復以前的緩衝池狀態,這些報告或維護作業將資料頁引入到緩衝池中(這些操作只需要這些資料頁),或者在執行其他一些非典型工作負載之後恢復以前的緩衝池狀態。

即使一個緩衝池的大小可以是很大(許多GB大小), InnoDB儲存到磁碟的緩衝池資料相比之下是非常小的。只有定位適當頁面所需的表空間id和頁面id被儲存到磁碟。這個資訊來自INNODB_BUFFER_PAGE_LRU INFORMATION_SCHEMA表。預設情況下,表空間ID和頁面ID資料儲存在一個名為ib_buffer_pool的檔案中,該檔案儲存在InnoDB資料目錄中。檔名和位置可以使用innodb_buffer_pool_filename配置引數修改。

因為資料會像常規資料庫操作一樣在緩衝池中快取和老化,所以如果磁碟頁最近更新了,或者DML操作涉及到尚未載入的資料,那麼沒有問題。載入機制會跳過不再存在的請求頁面。

底層機制涉及一個後臺執行緒,該執行緒被分派來執行轉儲和載入操作。

壓縮表中的磁碟頁以壓縮形式載入到緩衝池中。在DML操作期間訪問頁面內容時,像往常一樣對頁面進行不壓縮。因為解壓縮頁面是一個cpu密集型程式,所以對於併發性來說,在連線執行緒中執行操作比在執行緩衝池恢復操作的單個執行緒中執行操作更有效。

儲存和恢復緩衝池狀態的相關操作介紹如下主題:
設定緩衝池頁面轉儲百分比
在關機時儲存緩衝池狀態,在啟動時恢復它
線上儲存和恢復緩衝池狀態
顯示緩衝池轉儲進度
顯示緩衝池載入進度
中止緩衝池載入操作
使用效能方案監視緩衝池負載進度

設定緩衝池頁面轉儲百分比
在從緩衝池轉儲頁面之前,您可以透過設定innodb_buffer_pool_dump_pct選項來配置最近使用的要轉儲的緩衝池頁面百分比。如果您計劃在伺服器執行時轉儲緩衝池頁面,則可以動態配置該選項:

mysql> SET GLOBAL innodb_buffer_pool_dump_pct=40;
Query OK, 0 rows affected (0.00 sec)

如果您計劃在伺服器關閉時轉儲緩衝池頁面,請在配置檔案中設定innodb_buffer_pool_dump_pct。

[mysqld]
innodb_buffer_pool_dump_pct=40

當innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup預設啟用時,innodb_buffer_pool_dump_pct的預設值從100(轉儲所有頁面)改為25(轉儲最近使用的25%的頁面)。

在關機時儲存緩衝池狀態,在啟動時恢復它要在伺服器關閉時儲存緩衝池的狀態,請在關閉伺服器之前發出以下語句

mysql> SET GLOBAL innodb_buffer_pool_dump_at_shutdown=ON;
Query OK, 0 rows affected (0.00 sec)

Innodb_buffer_pool_dump_at_shutdown預設開啟。

要在伺服器啟動時恢復緩衝池狀態,需要在伺服器啟動時指定——innodb_buffer_pool_load_at_startup選項

mysqld --innodb_buffer_pool_load_at_startup=ON;

Innodb_buffer_pool_load_at_startup預設開啟

線上儲存和恢復緩衝池狀態
要在MySQL伺服器執行時儲存緩衝池的狀態,執行以下語句:

mysql> SET GLOBAL innodb_buffer_pool_dump_now=ON;
Query OK, 0 rows affected (0.01 sec)

要在MySQL執行時恢復緩衝池狀態,發出以下語句

mysql> SET GLOBAL innodb_buffer_pool_load_now=ON;
Query OK, 0 rows affected (0.01 sec)

顯示緩衝池轉儲進度
要在將緩衝池狀態儲存到磁碟時顯示進度,請發出以下語句:

mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status';
+--------------------------------+--------------------------------------------------+
| Variable_name                  | Value                                            |
+--------------------------------+--------------------------------------------------+
| Innodb_buffer_pool_dump_status | Buffer pool(s) dump completed at 220124 11:07:41 |
+--------------------------------+--------------------------------------------------+
1 row in set (0.01 sec)

如果操作尚未啟動,則返回not started。如果操作完成,則列印完成時間(例如110505 12:18:02完成)。如果操作正在進行中,會提供狀態資訊(例如dump buffer pool 5/7, page 237/2873)。

中止緩衝池載入操作
要中止緩衝池載入操作,發出以下語句:

mysql> SET GLOBAL innodb_buffer_pool_load_abort=ON;
Query OK, 0 rows affected (0.01 sec)

使用效能方案監視緩衝池負載進度
您可以使用Performance Schema監視緩衝池載入進度。

下面的例子演示瞭如何啟用stage/innodb/buffer pool load階段活動工具和相關的消費表來監視緩衝池載入進度。
1.啟用stage/innodb/buffer pool載入工具

mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES'
    -> WHERE NAME LIKE 'stage/innodb/buffer%';
Query OK, 0 rows affected (0.01 sec)
Rows matched: 1  Changed: 0  Warnings: 0

2. 啟用階段事件消費者表,其中包括events_stages_current、events_stages_history和events_stages_history_long。

mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES'
    -> WHERE NAME LIKE '%stages%';
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

3.透過啟用innodb_buffer_pool_dump_now轉儲當前的緩衝池狀態。

mysql> SET GLOBAL innodb_buffer_pool_dump_now=ON;
Query OK, 0 rows affected (0.00 sec)

4.檢查緩衝池轉儲狀態,確保操作完成

mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status'\G
*************************** 1. row ***************************
Variable_name: Innodb_buffer_pool_dump_status
        Value: Buffer pool(s) dump completed at 220124 11:27:10
1 row in set (0.01 sec)

5.透過啟用innodb_buffer_pool_load_now來載入緩衝池

mysql> SET GLOBAL innodb_buffer_pool_load_now=ON;
Query OK, 0 rows affected (0.01 sec)

6.透過查詢Performance Schema events_stages_current表,檢查緩衝池載入操作的當前狀態。WORK_COMPLETED列顯示了載入的緩衝池頁面的數量。WORK_ESTIMATED列提供了對剩餘工作的估計(以頁為單位)

mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED
FROM performance_schema.events_stages_current;
| EVENT_NAME                    | WORK_COMPLETED | WORK_ESTIMATED |
+-------------------------------+----------------+----------------+
| stage/innodb/buffer pool load |            153 |            167 |
+-------------------------------+----------------+----------------+
1 row in set (0.00 sec)

如果緩衝池載入操作已經完成,則events_stages_current表返回一個空集。在這種情況下,您可以檢查events_stages_history表來檢視已完成事件的資料。例如

mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED
    -> FROM performance_schema.events_stages_history;
+-------------------------------+----------------+----------------+
| EVENT_NAME                    | WORK_COMPLETED | WORK_ESTIMATED |
+-------------------------------+----------------+----------------+
| stage/innodb/buffer pool load |            190 |            190 |
+-------------------------------+----------------+----------------+
1 row in set (0.00 sec)

當使用innodb_buffer_pool_load_at_startup在啟動時載入緩衝池時,您也可以使用效能模式監視緩衝池的載入進度。在這種情況下,必須在啟動時啟用stage/innodb/ buffer pool載入工具和相關的消費者

用InnoDB標準監視器監視緩衝池
InnoDB Standard Monitor輸出,可以透過SHOW ENGINE InnoDB STATUS訪問,提供了InnoDB緩衝池操作的指標。Buffer pool metrics位於InnoDB Standard Monitor輸出的Buffer pool AND MEMORY部分,類似如下所示:

----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 274857984
Dictionary memory allocated 427952
Buffer pool size   16383
Free buffers       15907
Database pages     476
Old database pages 0
Modified db pages  0
Pending reads      0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 442, created 34, written 39
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 476, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------

下表描述了InnoDB Standard Monitor報告的InnoDB緩衝池指標
注意:在InnoDB標準監視器輸出中提供的每秒平均資料是基於上次列印InnoDB標準監視器輸出的時間。

InnoDB Buffer Pool指標
Total memory allocated: 分配給緩衝池的總記憶體(以位元組為單位)
Dictionary memory allocated:分配給InnoDB資料字典的總記憶體(以位元組為單位)
Buffer pool size:分配給緩衝池的頁面的總大小
Free buffers:緩衝池空閒列表的總頁大小。
Database pages:uffer pool LRU列表的總頁面大小
Old database pages:buffer pool old 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:buffer pool LRU列表的總頁面大小
I/O sum:最後50秒訪問的緩衝池LRU列表頁面總數
I/O cur:buffer pool LRU列表總訪問量
I/O unzip sum:訪問的緩衝池unzip_LRU列表頁面總數
I/O unzip cur:訪問的緩衝池unzip_LRU列表頁面總數

.young /s的標準只涉及到舊的頁面。它基於對頁面的訪問次數,而不是頁面的數量。一個給定的頁面可以有多個訪問,所有的訪問都被計算在內。如果您在沒有發生大型掃描時看到非常低的youngs/s值,您可能需要減少延遲時間或增加用於舊子列表的緩衝池的百分比。增加百分比會使舊子列表變大,因此該子列表中的頁面移動到尾部和被驅逐的時間會變長。這增加了頁面再次被訪問的可能性,並使其年輕

.non-youngs/s指標只與舊頁面相關。它基於對頁面的訪問次數,而不是頁面的數量。一個給定的頁面可以有多個訪問,所有的訪問都被計算在內。如果在執行大型表掃描時沒有看到很多非young /s值(而且young /s值很多),那麼就增加延遲值。

.young-making速率表示對所有緩衝池頁面的訪問,而不僅僅是對舊子列表中的頁面的訪問。young-making率和not率通常不會加到總的緩衝池命中率。舊子列表中的頁面點選會導致頁面移動到新的子列表中,但是新子列表中的頁面點選只有當它們與列表頭部有一定的距離時才會導致頁面移動到列表頭部,

.not(young-making率)的平均命中率是指由於定義延遲的innodb_old_blocks_time沒有被滿足頁面訪問並沒有導致使頁面年輕,或者由於新子列表頁面點選沒有導致頁面被搬到了頭。這個速率用於訪問所有緩衝池頁面,而不僅僅是訪問舊子列表中的頁面。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26015009/viewspace-2871745/,如需轉載,請註明出處,否則將追究法律責任。

相關文章