簡單分析mysql的InnoDB存儲引擎的內存架構


在這裏插入圖片描述

上圖是mysql官方文檔中提供的InnoDB架構圖,左側是內存架構,右側則是磁盤架構。本文主要對內存架構簡單分析下,下次再說磁盤架構。

首先,我們瞭解一些InnoDB的基礎概念:
InnoDB中數據從磁盤加載進內存的最小邏輯單位是16kb(16384個字節),叫做“頁”(page)。
:就會想爲什麼這麼定義呢?如果一次我只讀1kb的數據,那IO時不就浪費了15kb的空間嗎?
:這就是預讀的思想,它會認爲你讀取這個數據後,很快就會讀取這條數據後的數據了。所以就提前把這條數據相鄰的數據也加載進內存

讀緩存(buffer pool)

我們都知道,與磁盤的io是很消耗性能的。爲了減少與磁盤的io次數。InnoDB在內存中開闢了一個buffer pool的區域(緩衝區),下次讀取的時候,會先在這個緩衝區找,如果沒有再去磁盤上找。修改數據的時候,會先修改內存區域中的數據,然後在mysql的後臺裏有一些線程專門進行批量刷新到磁盤的操作。這樣就能提高我們應用的吞吐量。
查看buffer pool信息的命令:show variables like '%innodb_buffer_pool%';
在這裏插入圖片描述
如上圖:innodb_buffer_pool_size的默認值爲402653184kb也就是128mb。
:如果這個pool滿了怎麼辦?
:它會採用一種淘汰機制:LRU算法,或許你在別的地方見過或聽說過。也就是會淘汰掉最近最少使用數據。當然,mysql並不是採用普通的LRU算法,而是對它進行了升級並使用。爲了解決“預讀失效”,“緩衝池污染”的問題。(這裏就簡單的瞭解一下,詳細的請看這篇文章)。

寫緩存(change buffer)

對於讀請求,緩衝池能夠減少磁盤IO,提升性能。問題來了,那寫請求呢?增刪改的時候如果沒有在buffer pool中命中,那麼至少要和磁盤進行一次io,加載進內存才能操作。有沒有更好的方式?
寫緩存在MySQL5.5之前,叫插入緩衝(insert buffer),只針對insert做了優化;現在對delete和update也有效,叫做寫緩衝(change buffer)。
在我們修改數據時,如果數據所在的頁不是唯一索引,那麼數據在修改的時候InnoDB不必進行唯一性檢查了。這個時候根本不需要先把數據從磁盤加入到內存中,而是直接把修改的記錄放在change Buffer緩衝池裏,然後有後臺的線程批量的刷新到磁盤。
查看change buffer信息的命令:show variables like '%innodb_change_buffer%';
在這裏插入圖片描述
如上圖:
innodb_change_buffer_max_size:配置寫緩衝的大小,佔整個緩衝池的比例,默認值是25%,最大值是50%。(寫多讀少的業務,才需要調大這個值,讀多寫少的業務,25%綽綽有餘)
innodb_change_buffering:配置哪些寫操作啓用寫緩衝,可以設置成all/none/inserts/deletes等。

redo log

上面說到了,數據增刪改的操作,那麼問題來了。
:如果修改的數據還沒刷到磁盤上,mysql就掛了怎麼說,那change buffer裏的數據不就玩完了嗎?當然這肯定是有解決方案的。
:爲了防止內存中的增刪改數據丟失,InnoDB裏設計了一個日誌文件redo log,把這些修改寫入到這個日誌文件裏持久化到磁盤,萬一發生崩潰,重啓時就會從redo log文件中讀取數據,把這些數據恢復到磁盤上。這就是mysql對崩潰恢復做的處理。相當於對內存區域的持久化。
:那這寫入到redo log也是與磁盤IO,那還不如直接寫到數據庫的磁盤類。反正都是磁盤IO憑啥寫入到redo log快?
:這就要扯到隨機IO和順序IO了。
隨機IO:假設我們所需要的數據是隨機分散在磁盤的不同頁的不同扇區中的,那麼找到相應的數據需要等到磁臂(尋址作用)旋轉到指定的頁,然後盤片尋找到對應的扇區,才能找到我們所需要的一塊數據,一次進行此過程直到找完所有數據,這個就是隨機IO,讀取數據速度較慢。
順序IO:假設我們已經找到了第一塊數據,並且其他所需的數據就在這一塊數據後邊,那麼就不需要重新尋址,可以依次拿到我們所需的數據,這個就叫順序IO。
很明顯,順序IO的效率遠高於隨機IO,而寫入到redo log 就是順序IO,可以延遲刷盤的時機,提高系統的吞吐量。
注意:redo log也不是發生一次sql的操作就發生IO寫入一次的,它也有一個緩衝區Log Buffer,也是記錄一系列操作後在通過線程刷新到redo log文件裏。InnoDB中才有redo log,主要就是記錄數據頁的改動,redo log文件默認48Mb,超了就會覆蓋,覆蓋前會先刷盤。
在這裏插入圖片描述
<<上一篇:MYSQL開篇:mysql的體系結構

>>下一篇:InnoDB存儲引擎的磁盤架構

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