高性能Mysql-存儲引擎(InnoDB)

MySQL將每個數據庫(也可以稱爲schema)保存爲數據目錄下的一個子目錄,創建表時,MySQL會在數據庫子目錄下創建一個和表同名的 .frm文件保存表的定義。(也因此MySQL數據庫和表的定義對大小寫的敏感性與具體平臺密切相關)


今天考完網易的數據庫管理員筆試,其中一道問答題就說到了InnoDB的特性,OK,我雖然看過這節,但是答的一趟糊塗。再把這個博文改一改。
InnoDB三大性質參考http://www.2cto.com/database/201306/219331.html


一、InnoDB

InnoDB是MySQL的默認事務型引擎,也是最重要,使用最廣泛的存儲引擎。他是用來處理大量的短期事務,短期事務大部分情況是正常提交的,很少會被回滾。
InnoDB的性能和自動崩潰恢復特性,使得它在非事務型的需求中也很流行。

InnoDB的歷史:
2008年發佈InnoDB plugin,適用於MySQL 5.1 版本,但當時MySQL默認還是使用舊的InnoDB引擎。在Oracle收購Sun後發佈的MySQL5.5中才徹底使用InnoDB plugin替代了舊版本的InnoDB

這個新版本支持一些新特性,例如利用排序創建索引、刪除或者增加索引時不需要複製全表數據、新的支持壓縮的存儲格式,新的大型列值如BLOB的存儲方式,以及文件格式管理等。

  1. InnoDB的數據存儲在表空間中,表空間是由InnoDB管理的一個黑盒子,由一系列的數據文件組成,4.1版本之後,可以將每個表的數據和索引存放在單獨的文件中。

  2. 採用MVCC來支持高併發,並且實現4個標準的隔離級別,默認級別是REPEATABLE READ(可重複讀),並且通過間隙鎖策略防止幻讀的出現。

  3. InnoDB表示基於聚族索引建立的,聚族索引對主鍵查詢有很高的性能,若表上的索引較多的話,主鍵應當儘可能的小。

  4. InnoDB內部做了很多優化,包括從磁盤讀取數據時採用的可預測性預讀,能夠自動在內存中創建hash索引以加速讀操作的自適應哈希索引。

三大特性:

1. 插入緩衝(insert buffer)
對於非聚集索引的插入和更新,不是每一次直接插入索引頁中,而是首先判斷插入的非聚集索引頁是否在緩衝池中,如果在,則直接插入,否則,先放入一個插入緩衝區中。好似欺騙數據庫這個非聚集的索引已經插入到葉子節點了,然後再以一定的頻率執行插入緩衝和非聚集索引頁子節點的合併。
大大提高了對非聚集索引執行插入和修改操作的性能。

2. 兩次寫(double write)
如果說插入緩衝是爲了提高寫性能的話,那麼兩次寫是爲了提高可靠性,犧牲了一點點寫性能。

部分寫失效
當數據庫正在從內存向磁盤寫一個數據頁時,數據庫宕機,從而導致這個頁只寫了部分數據,這就是部分寫失效,它會導致數據丟失。這時是無法通過重做日誌恢復的,因爲重做日誌記錄的是對頁的物理修改,如果頁本身已經損壞,重做日誌也無能爲力。
這裏寫圖片描述
1)內存中的兩次寫緩衝(doublewrite buffer),大小爲2MB
2)磁盤上共享表空間中連續的128頁,大小也爲2MB

其原理是這樣的:
1)當刷新緩衝池髒頁時,並不直接寫到數據文件中,而是先拷貝至內存中的兩次寫緩衝區。
2)接着從兩次寫緩衝區分兩次寫入磁盤共享表空間中,每次寫入1MB
3)待第2步完成後,再將兩次寫緩衝區寫入數據文件

其中第2步是額外的性能開銷,但由於磁盤共享表空間是連續的,因此開銷不是很大

三、自適應哈希索引(adaptive hash index)
由於innodb不支持hash索引,但是在某些情況下hash索引的效率很高,於是出現了 adaptive hash index功能,innodb存儲引擎會監控對錶上索引的查找。如果觀察到建立hash索引可以提高性能的時候,則自動建立hash索引。

二、MyISAM
5.1之前版本採用的存儲引擎,提供了包括全文索引,壓縮,空間函數等,但MyISAM不支持事務和行級鎖,而且有個缺陷就是崩潰後無法安全恢復。MyISAM會將表存儲在兩個文件中:數據文件和索引文件,分別以.MYD和.MYI爲擴展名

三、MySQL內建的其他存儲引擎
Archive引擎
只支持Insert和select操作,select查詢需要執行全表掃描,適合日誌和數據採集類應用。支持行級鎖和高併發的插入。

Blackhole引擎
CSV引擎
Federated引擎
Memory引擎
Merge 引擎
NDB集羣引擎

四、如何選擇合適的引擎
大部分情況下,InnoDB都是正確的選擇 除非需要用到某些InnoDB不具備的特性,並且沒有其他辦法可以替代,否則都應該優先選擇InnoDB引擎。例如,要用到全文索引,建議優先考慮InnoDB加上Sphinx的組合。

除非萬不得已,否則建議不要混合使用多種存儲引擎,否則可能帶來一系列複雜的問題,以及一些潛在的bug和邊界問題。

日誌型應用

假設需要實時地記錄一臺中心電話交換機的每一通電話的日誌到MySQL中,或者通過Apache的mod_log_sql模塊將網站的所有訪問信息直接記錄到表中。

這一類應用的插入速度有很高的要求,數據庫不能成爲瓶頸。MyISAM或者Archive存儲引擎對這類應用比較合適,因爲他們開銷低,插入速度非常快。

做分析報表時,利用MySQL內置的複製方案將數據複製一份到備庫,然後在備庫,然後在備庫上執行比較消耗時間和CPU的查詢。

不要輕易相信“MyISAM比InnoDB快”之類的經驗之談,這個結論往往不是絕對的。在很多我們已知的場景中,InnoDB的速度都可以讓MyISAM望塵莫及。

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