走近InnoDB記憶體結構

2021-10-05 01:24:16 字數 2538 閱讀 9148

log buffer

adaptive hash index

參考我們先來看看mysql官方給出的innodb的整體結構,如下圖,從圖中可以看出,大致可以分為左右兩個部分,左邊描述的是記憶體結構,就是本文討論的主要內容,右邊描述的是磁碟結構,會在之後的文章裡講述。

從上圖可以看出,內容結構又可以細分為三個部分,分別為buffer pool、adaptive hash index和log buffer,接下來我們就來看看他們分別是什麼,又有什麼用呢。

buffer pool(緩衝池)是主記憶體中的乙個區域,innodb在訪問表和索引資料時將快取在其中,來加速資料訪問。大家都知道,mysql讀取資料的最小單位是page(頁),就算你一次查詢的結果只有一行資料,但是mysql會把這行資料所在的page載入到buffer pool,所以buffer pool中的結構也是page,每乙個page可能包含多行資料。

lru為了提高快取的命中率,每一種快取都會有適合自己的快取淘汰演算法,buffer pool也不例外。buffer pool使用的是lru(最近最少使用)的變體,這種演算法被廣泛應用,例如作業系統、redis等等。這種演算法能最大化頁面命中率。關於這種演算法的更多資訊,可自行google。

buffer pool list

當需要空間將新頁新增到緩衝池時,將收回最近使用最少的頁,並將新頁新增到列表的中間。這個中點將列表分為兩個子列表:

這裡說一下這個變體演算法的過程:

你可能會覺得疑惑,為什麼要在列表的「中點」(也就是舊子列表的頭部)插入,再通過訪問舊子列表使其插入列表的頭部(也就是新子列表的頭部),而不是直接插入列表的頭部呢?這不是多此一舉麼?

其實並不是多次一舉,你試想一下,新子列表中存放的是我們大量的熱點資料,這個時候有乙個大表的全表查詢或者mysqldump(邏輯備份),如果是直接插入列表的頭部會有什麼結果,我們新子列表中的所有熱點資料全部被「老化」到舊子列表中,甚至直接被淘汰,其實我們並不希望如此。因為才會選擇通過再次訪問舊子列表的頁使其變為「年輕」。

buffer pool配置

flush

當記憶體資料頁跟磁碟資料頁內容不一致的時候,我們稱這個記憶體頁為「髒頁」。

正常執行中的例項,資料寫入後的最終落盤,是從redo log更新過來的還是從buffer pool更新過來的呢?

實際上,redo log並沒有記錄資料頁的完整資料,所以它並沒有能力自己去更新磁碟資料頁。

所以說,redo log只是用來恢復記憶體中的資料,更新資料是從記憶體頁更新到磁碟的。

刷髒頁雖然是常態,但是出現以下這兩種情況,都是會明顯影響效能的:

所以,innodb需要有控制髒頁比例的機制,來盡量避免上面的這兩種情況。

change buffer

change buffer(更改快取區),是一種特殊的資料結構,當輔助索引頁不在buffer pool中時,它會將更改快取到輔助索引頁。由插入、更新或刪除操作(dml)引起的緩衝更改將在稍後由其他讀取操作將頁載入到buffer pool中時合併。

與聚集索引不同,二級索引通常是非唯一的,插入二級索引的順序相對隨機。類似地,刪除和更新可能會影響索引樹中不相鄰的輔助索引頁。當受影響的頁被其他操作讀取到buffer pool中時,合併快取的更改可以避免從磁碟將輔助索引頁讀取到緩衝池中所需的大量隨機i/o訪問。

所以,change buffer中儲存的是更改了的輔助索引頁。

如果索引包含降序索引列或主鍵包含降序索引列,則不支援對輔助索引進行更改緩衝。

log buffer(日誌緩衝區),用於儲存要寫入磁碟上的日誌檔案的資料。日誌緩衝區大小由innodb_log_buffer_size變數定義。預設大小為16mb。日誌緩衝區的內容定期重新整理到磁碟(寫入重做日誌檔案)。大型日誌緩衝區使大型事務能夠執行,而無需在事務提交之前將重做日誌資料寫入磁碟。因此,如果您有更新、插入或刪除許多行的事務,增加日誌緩衝區的大小可以節省磁碟i/o。

innodb_flush_log_at_trx_commit變數控制如何將日誌緩衝區的內容寫入並重新整理到磁碟。該innodb_flush_log_at_timeout變數控制日誌重新整理頻率。

adaptive hash index(自適應雜湊索引),使innodb可以在不犧牲事務功能或可靠性的情況下,在工作負載和緩衝池有足夠記憶體的適當組合的系統上執行更像是記憶體資料庫。

使用索引關鍵字的字首構建雜湊索引。字首可以是任意長度,並且可能只有b樹中的某些值出現在雜湊索引中。雜湊索引是根據需要為經常訪問的索引頁構建的

就像上面整體結構圖中描述的一樣,自適應雜湊索引可以加快對buffer pool中索引頁的訪問。

[1] mysql 5.7 reference manual.

[2] mysql實戰45講.

INNODB記憶體結構

innodb記憶體結構如下圖 innodb高速緩衝對innodb很重要 innodb不依賴os,而自己快取了所有資料,包括索引資料,行資料,等等,這點跟myisam有差別 myisam的資料依靠os的pagecache進行快取 應該把它設定大一些,建議設定為可用ram的50 80 查詢或更新需要對i...

InnoDB的記憶體結構和特性

緩衝池 innodb儲存引擎是基於磁碟儲存的,並將其中的記錄按照頁的方式進行管理。但是由於cpu速度和磁碟速度之間的鴻溝,基於磁碟的資料庫系統通常使用緩衝池記錄來提高資料庫的的整體效能。在資料庫中進行讀取操作,首先將從磁碟中讀到的頁放在緩衝池中,下次再讀相同的頁中時,首先判斷該頁是否在緩衝池中。若在...

InnoDB體系結構之記憶體篇

前言,對於計算機來說,cpu 的運算速率要比記憶體讀寫速率快的多,記憶體的讀寫效率比磁碟的讀寫要快得多。為了解決 cpu 執行效率與記憶體讀寫速度不匹配的問題,就出現了cpu 快取。將記憶體中的一小部分資料在 cpu中快取起來,這樣就加快了 cpu 處理資料的能力。其實在任意兩種 速度相差較大的硬體...