InnoDB內存數據結構

InnoDB內存相關的數據結構主要包含以下幾種:

  • Buffer Pool
  • Change Buffer
  • Adaptive Hash Index
  • Log Buffer

Buffer Pool

Buffer Pool 是在主存的一片區域,主要用來緩存表和索引數據供InnoDB訪問。Buffer Pool允許頻繁訪問的數據可以加速直接從內存讀取。專業的服務器,一般使用80%的物理內存作爲Buffer Pool。
爲了提高大量讀取操作的性能,Buffer Pool被分割爲多個pages。爲了高效管理緩存,buffer pool的實現是作爲一個linked list。很少使用的數據採用LRU算法淘汰。

Buffer Pool LRU 算法

BufferPool 採用LRU算法淘汰。當需要新增一個page到BufferPool時,最近最少使用的page將會被驅逐,一個新page會被加入中間。中間插入的策略會把list切分爲兩個list:

  • 在頭部,新頁會被最新訪問
  • 在尾部,老的page不會被頻繁訪問
    在這裏插入圖片描述

這個算法切分list爲兩個sublist。old sublit 存儲最少使用的頁,這些爺會被優先移除。算法的主要操作包含:

  • 3/8 的buffer pool容量用作old sublist
  • 插入元素的中間節點爲新元素list的末尾和老元素list的頭部
  • 當InnoDB讀取一個page到Buffer Pool,首先會插入數據到中間(老數據的頭部)。
  • 訪問老數據的一個page,會使這部分數據移動到新數據的頭部。

Buffer Pool Configuration

  • buffer pool size 配置文檔參考: https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool-resize.html
  • 設置多個buffer pool instance 參考文檔:https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-buffer-pools.html

監控 Buffer Pool

SHOW ENGINE INNODB STATUS 語句可以查看Buffer Pool的使用情況

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 137363456; in additional pool allocated 0
Dictionary memory allocated 223332
Buffer pool size   8192
Free buffers       1
Database pages     8190
Old database pages 3003
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 749906, not young 152695637
0.00 youngs/s, 0.00 non-youngs/s
Pages read 3988618, created 530179, written 4842443
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: 8190, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
  • youngs/s 指標只應用於old pages。主要基於訪問page的數而不是page總數。如果發現很低的youngs/s,需要降低淘汰時間或者減少 buffer pool中的old sublist大小。
  • non-youngs/s也只用於old pages。主要基於訪問page的數而不是page總數。
  • young-making 適用於所有的buffer pool

Change Buffer

change buffer 是一個特殊的緩存,主要緩存二級索引頁,而這些索引頁不在buffer pool.Change Buffer的更新會基於 INSERT, UPDATE, or DELETE operations (DML) 操作結果,這些將會通過其他的讀取操作合併到buffer pool.

在這裏插入圖片描述
與聚集索引不同,二級索引不唯一的,插入二級索引也是非順序的。同樣的,刪除和更新操作可能影響的二級索引不在同一個索引樹。合併緩存發生在,受影響的行再其他操作讀取進入buffer pool時,避免大量的隨機IO操作讀取二級索引到buffer pool.
合併Change buffer有可能花費幾個小時,當大量的行數和二級索引更新時。在這段時間,會產生大量的IO操作。 Change buffer merging 也可能發生於一個事務提交,或者一個停機重啓操作。
在內存中, change buffer 屬於buffer pool的一部分。在磁盤上,change buffer屬於系統表空間。

監控 Change Buffer

-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 4425293, used cells 32, node heap has 1 buffer(s)
13577.57 hash searches/s, 202.47 non-hash searches/s

Adaptive Hash Index 自適應哈希索引

自適應哈希索引特性使InnoDB能夠在具有適當的工作負載和足夠的緩衝池內存的系統上執行更像內存中的數據庫,而不犧牲事務特性或可靠性。自適應hash索引可以通過開啓 innodb_adaptive_hash_index變量開啓,或者通過–skip-innodb-adaptive-hash-index關閉。
根據搜索模式,哈希索引根據使用索引鍵的前綴構建。前綴可以是任意長度,並且可能只有B樹中的某些值出現在哈希索引中。哈希索引是根據需要爲經常訪問的索引頁構建的。

Log Buffer

Log buffer是內存中的一塊區域,主要保存寫入硬盤的日誌數據。Log Buffer的內存大小通過參數innodb_log_buffer_size指定。默認大小爲16MB.
innodb_flush_log_at_trx_commit變量控制什麼時候log buffer會被寫入磁盤。innodb_flush_log_at_timeout 變量控制log刷新的頻率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章