知識點:瞭解InnoDB存儲引擎的內存池

每日一個知識點系列的目的是針對某一個知識點進行歸納性總結,可在一分鐘內完成知識點的閱讀理解。前端

此處不涉及詳細的原理性解讀,只做爲一種拋磚引玉。web

真正的理解必定是你自我研究探索所收穫的知識,加入組織帶你一塊兒進步成長。算法

經過前幾天的知識點咱們知道,在Innodb體系架構裏,主要包含後臺線程和內存兩大塊,今天就來講下Innodb體系架構裏內存的一些知識點。架構圖以下:數據庫

Innodb的內存

老規矩,先上圖,從全局看一下:緩存

目前咱們能夠看出,InnoDB內存主要有兩大部分:微信

  • 緩衝池
  • 重作日誌緩衝

InnoDB存儲引擎是基於磁盤存儲的,並將其中的記錄按照頁的方式進行管理。架構

所以可將其視爲基於磁盤的數據庫系統(Disk-base Database)。併發

在數據庫系統中,因爲CPU速度與磁盤速度之間的鴻溝,基於磁盤的數據庫系統一般使用緩衝池技術來提升數據庫的總體性能編輯器

緩衝池

緩衝池簡單來講就是一塊內存區域,經過內存的速度來彌補磁盤速度較慢對數據庫性能的影響。性能

緩衝池中緩存的數據頁類型:

  • 索引頁
  • 數據頁
  • undo頁
  • 插入緩衝(insert buffer)
  • 自適應哈希索引(adaptive hash index)
  • InnoDB存儲的鎖信息(lock info)
  • 數據字典信息(data dictionary

讀數據操做

  • 首先將從磁盤讀到的頁存放在緩衝池中,這個過程稱爲將頁「FIX」在緩衝池中

  • 下一次再讀相同的頁時,首先判斷該頁是否在緩衝池中

  • 若在緩衝池中,稱該頁在緩衝池中被命中,直接讀取該頁。不然,讀取磁盤上的頁

寫數據操做

  • 首先修改在緩衝池中的頁,而後再以必定的頻率刷新到磁盤上

  • 頁從緩衝池刷新回磁盤的操做並非在每次頁發生更新時觸發

  • 經過一種稱爲Checkpoint的機制刷新回磁盤

配置參數:

  • innodb_buffer_pool_instances, 緩衝池實例個數默認1,InnoDB 1.0.x版本開始使用,每一個頁根據哈希值平均分配到不一樣緩衝池實例中。減小數據庫內部的資源競爭,增長數據庫的併發處理能力。
  • innodb_buffer_pool_size,緩衝池大小

命令參數:

  • 可經過命令查看緩衝池大小 SHOW VARIABLES LIKE 'innodb_buffer_pool_size'
  • 經過命令可查看緩衝池實例個數 SHOW VARIABLES LIKE 'innodb_buffer_pool_instances'

緩衝池的管理

緩衝池是一個很大的內存區域,其中存放各類類型的頁。其實這麼大的內存區域是經過LRU算法來進行管理的,而這裏的LRU也是InnoDB 對傳統的作了一些優化

LRU List

傳統LRU:

  • 最頻繁使用的頁在LRU列表的前端
  • 最少使用的頁在LRU列表的尾端
  • 緩衝池不能存放新讀取到的頁時,將首先釋放LRU列表中尾端的頁

InnoDB改進版LRU:

  • LRU列表中加入了midpoint位置
  • 新讀取到的頁是放入到LRU列表的midpoint位置
  • 默認配置下,該位置在LRU列表長度的5/8處。midpoint位置可由參數innodb_old_blocks_pct控制
  • 引入innodb_old_blocks_time 參數,用於表示頁讀取到mid位置後須要等待多久纔會被加入到LRU列表的熱端

Free List

  • LRU列表用來管理已經讀取的頁,但當數據庫剛啓動時,LRU列表是空的,即沒有任何的頁。這時頁都存放在Free列表中.

  • 當須要從緩衝池中分頁時,首先從Free列表中查找是否有可用的空閒頁,如有則將該頁從Free列表中刪除,放入到LRU列表中。不然,根據LRU算法,淘汰LRU列表末尾的頁,將該內存空間分配給新的頁

  • 當頁從LRU列表的old部分加入到new部分時,稱此時發生的操做爲page made young,而由於innodb_old_blocks_time的設置而致使頁沒有從old部分移動到new部分的操做稱爲page not made young


  • 能夠經過命令SHOW ENGINE INNODBSTATUS來觀察LRU列表及Free列表的使用狀況和運行狀態

Flush List

  • LRU列表用來管理緩衝池中頁的可用性,Flush列表用來管理將頁刷新回磁盤,兩者互不影響

  • 在LRU列表中的頁被修改後,稱該頁爲髒頁(dirty page),即緩衝池中的頁和磁盤上的頁的數據產生了不一致。

  • 這時數據庫會經過CHECKPOINT機制將髒頁刷新回磁盤,而Flush列表中的頁即爲髒頁列表。

  • 髒頁既存在於LRU列表中,也存在於Flush列表中。

緩衝池中的頁還可能會被分配給自適應哈希索引、Lock信息、InsertBuffer等頁,而這部分頁不須要LRU算法進行維護,所以不存在於LRU列表中。

重作日誌緩衝(redo log buffer)

  • InnoDB存儲引擎首先將重作日誌信息先放入到這個緩衝區,而後按必定頻率將其刷新到重作日誌文件

  • 重作日誌緩衝通常不須要設置得很大,由於通常狀況下每一秒鐘會將重作日誌緩衝刷新到日誌文件

  • 該值可由配置參數innodb_log_buffer_size控制,默認爲8MB

  • 可經過命令查看大小  SHOW VARIABLES LIKE  'innodb_log_buffer_size'

何時刷新到磁盤?

  • Master Thread每一秒將重作日誌緩衝刷新到重作日誌文件

  • 每一個事務提交時會將重作日誌緩衝刷新到重作日誌文件

  • 當重作日誌緩衝池剩餘空間小於1/2時,重作日誌緩衝刷新到重作日誌文件

往期推薦

知識點:瞭解InnoDB的後臺線程

你不知道的內存知識

Spring Boot 系列 :關於Kafka消息發送的事兒

Spring Boot 系列:日誌動態配置詳解

Spring Boot 系列:最新版優雅停機詳解



本文分享自微信公衆號 - 架構技術專欄(jiagoujishu)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索