InnoDB是事務安全的MySQL存儲引擎,設計上採用了相似於Oracel數據庫的架構。一般來講,InnoDB存儲引擎是OLTP應用中核心表的首選存儲引擎。同時,也正是由於InnoDB的存在,才使MySQL數據庫變得更有魅力。本文將介紹InnoDB存儲引擎的體系架構及其不一樣於其餘存儲引擎的特性。算法
該引擎是第一個完整支持ACID事務的MySQL引擎,其特色是行鎖設計、支持MVCC、支持外鍵、提供一致性非鎖定讀,同時被設計用來最有效的利用以及使用內存和CPU。數據庫
從下圖可見,InnoDB存儲引擎有多個內存塊,能夠認爲這些內存塊組成了一個大的內存池,負責以下工做:緩存
InnoDB存儲引擎是多線程的模型,所以氣候態有多個不一樣的後臺線程,負責處理不一樣的任務。安全
1.Master Thread
Master Thread是很是核心的後臺線程,主要負責將緩衝池中的數據異步刷新到磁盤,保證數據的一致性,包括髒頁的刷新、合併插入緩衝、UNDO頁的回收等。
2.IO Thread
在InnoDB存儲引擎中大量使用了AIO(Async IO)來處理寫IO請求,這樣能夠極大提升數據庫的性能。而IO Thread的工做主要是負責這些IO請求的回調(call back)處理。
3.Purge Thread
事務被提交後,其所使用的undolog可能再也不須要,所以須要PurgeThread來回收已經使用並分配的undo頁。
4.Page Cleaner Thread
將髒頁的刷新操做都放入到單獨的線程中來完成。而七畝地是爲了減輕原master Thread的工做及對於用戶查詢線程的阻塞,進一步提升InnoDb存儲引擎的性能。數據結構
一、緩衝池
InnoDB存儲引擎是基於磁盤存儲的,並將其中的記錄按照頁的方式進行管理。所以可將其視爲基於磁盤的數據庫系統。在數據庫系統中,因爲CPU速度與磁盤速度之間的鴻溝,基於磁盤的數據庫系統一般使用緩衝池技術來提升數據庫的總體性能。多線程
緩衝池簡單來講就是一塊內存區域,經過內存的速度來彌補磁盤速度較慢對數據庫性能的影響。在數據庫中進行讀取頁的操做,首先將從磁盤讀到的頁放在緩衝池中,這個過程稱爲將頁「FIX」在緩衝池中。下一次再讀取相同的頁時,首先判斷該頁是否在緩衝池中。若在緩衝池中,稱該頁在緩衝池中被命中,直接讀取該頁。不然,讀取磁盤上的頁。架構
對於數據庫中頁的修改操做,則首先修改在緩衝池中的頁,而後再以必定的頻率刷新到磁盤上。須要注意的是,頁從緩衝池刷新回磁盤的操做並非在每次頁發生更新時觸發,而是經過一種稱爲Checkpoint的機制刷新回磁盤。一樣,這也是爲了提升數據庫總體性能。異步
綜上所述,緩衝池大小直接影響着數據庫的總體性能。性能
二、LRU List
這段主要介紹InnoDB存儲引擎怎麼對緩衝池進行內存管理的。優化
在InnoDB存儲引擎中一樣適用LRU算法對緩衝池進行管理。稍有不一樣的是InnoDB存儲引擎對傳統的LRU算法作了一些優化在InnoDB的存儲引擎中,LRU列表還加入了midpoint位置。新讀取到的頁,雖然是最新訪問的頁,但並非直接放入到LRU列表的首部,而是放入到LRU列表的mindpoint位置。這個算法在InnoDB存儲引擎下被稱爲mindpoint insertion strategy。在默認配置下,該位置在LRU列表長度的5/8處。
三、重作日誌緩衝
InnoDB存儲引擎的內存區除了有緩衝區外,還有重作日誌緩衝。InnoDB存儲引擎首先將重作日誌信息放入到這個緩衝區,而後按必定平率將其刷新到重作日誌文件。重作日誌緩衝通常不須要設置得很大,由於通常狀況下每一秒會將重作日誌緩衝刷新到日誌文件,所以用戶只需保證每秒產生的事務量在這個緩衝大小以內便可。
四、額外的內存池
在對一些數據結構自己進行內存分配時,須要從額外的內存池中進行申請,當該區域的內存不夠使,會從緩衝池中進行申請。
前面已經講到了,緩衝池的設計目的爲了協調CPU與磁盤速度的鴻溝。所以頁的操做首先都是在緩衝池中完成的。若是一條DML(數據操做語言)語句,如Update或Delete改變了頁中的記錄,那麼此時頁時髒的,即緩衝池中頁的版本要比磁盤的新。數據庫須要將新的版本的頁從緩衝池刷新到磁盤。
假若每一次一個頁發生變化,就將新頁的版本刷新到磁盤,那麼這個開銷是很是大的。若熱點數據集中在某幾個頁中,那麼數據庫的性能將變得很是差。同時,若是在從緩衝池將頁的新版本刷新到磁盤時發生宕機,那麼數據就不能恢復了。爲了不發生數據丟失的問題,當前事務數據庫系統廣泛都採用Write Ahead Log策略,即當事務提交時,先寫重作日誌,再修改頁。當因爲發生宕機而致使數據丟失時,經過重作日誌來完成數據的恢復。這也是事務ACID中D(Durability持久性)的要求。
Checkpoint(檢查點)技術的目的是解決如下幾個問題:
當數據庫發生宕機時,數據庫不須要重作全部的日誌,由於Checkpoint以前的頁都已經刷新回磁盤。故數據庫只需對Checkpoint後的重作日誌進行恢復。這樣就大大縮短了恢復時間。
此外,當緩衝池不夠用時,根據LRU算法會溢出最近最少使用的頁,此頁即爲髒頁,那麼須要強制執行Checkpoint,將髒頁也就是頁的最新版本刷新回磁盤。
在InnoDB存儲引擎中,Checkpoint發生的時間、條件及髒頁的選擇等都很是複雜。而Checkpoint所作的事情無外乎是將緩衝池中的髒頁刷回到磁盤。不一樣之處在於每次刷新多少頁到磁盤,每次從哪裏取髒頁,以及什麼時間觸發Checkpoint。在InnoDB存儲引擎內部,有兩種Checkpoint,分別爲:
但如果數據庫在運行時也是用Sharp Checkpoint,那麼數據的可用性就會受到很大的影響。故在InnoDB存儲引擎內部使用Fuzzy Checkpoint進行頁的刷新,即只刷新一部分髒頁,而不是刷新全部的髒頁。