1. 程式人生 > 其它 >MySQL各儲存引擎

MySQL各儲存引擎

MySQL中的資料用各種不同的技術儲存在檔案(或者記憶體)中。這些技術中的每一種技術都使用不同的儲存機制、索引技巧、鎖定水平並且最終提供廣泛的不同的功能和能力。通過選擇不同的技術,你能夠獲得額外的速度或者功能,從而改善你的應用的整體功能。這些不同的技術以及配套的相關功能在MySQL中被稱作儲存引擎(也稱作表型別)。MySQL預設配置了許多不同的儲存引擎,可以預先設定或者在MySQL伺服器中啟用。你可以選擇適用於伺服器、資料庫和表格的儲存引擎,以便在選擇如何儲存你的資訊、如何檢索這些資訊以及你需要你的資料結合什麼效能和功能的時候為你提供最大的靈活性。
使用以下命令可以檢視MySQL支援的引擎:

mysql> show engines;

一、InnoDB儲存引擎

InnoDB是MySQL的預設事務型引擎,也是最重要、使用最廣泛的儲存引擎。它被設計 用來處理大量的短期(short-lived)事務,短期事務大部分情況是正常提交的,很少會被回滾。InnoDB的效能和自動崩潰恢復特性,使得它在非事務型儲存的需求中也很流 行。除非有非常特別的原因需要使用其他的儲存引擎,否則應該優先考慮InnoDB引擎。 □D>如果要學習儲存引擎,InnoDB也是一個非常好的值得花最多的時間去深入學習的物件, 收益肯定比將時間平均花在每個儲存引擎的學習上要高得多。

InnoDB的歷史

InnoDB有著複雜的釋出歷史,瞭解一下這段歷史對於理解InnoDB很有幫助。2008年, 釋出了所謂的InnoDB plugin,適用於MySQL 5.1版本,但這是Oracle建立的下一代 InnoDB引擎,其擁有者是InnoDB而不是MySQL。這基於很多原因,這些原因如果要一一道來,恐怕得喝掉好幾桶啤酒。MySQL預設還是選擇了整合舊的InnoDB引擎。當 然使用者可以自行選擇使用新的效能更好、擴充套件性更佳的InnoDB plugin來覆蓋舊的版本。 直到最後,在Oracle收購了 Sun公司後釋出的MySQL 5.5中才徹底使用InnoDB plugin 替代了舊版本的InnoDB (是的,這也意味著InnoDB plugin已經是原生編譯了,而不是編譯成一個外掛,但名字已經約定俗成很難更改)。

這個現代的InnoDB版本,也就是MySQL 5.1中所謂的InnoDB plugin,支援一些新特性, 諸如利用排序建立索引(building index by sorting)、刪除或者增加索引時不需要複製全表資料、新的支援壓縮的儲存格式、新的大型列值如BLOB的儲存方式,以及檔案格式管 理等。很多使用者在MySQL 5.1中沒有使用InnoDB plugin,或許是因為他們沒有注意到有這個區別。所以如果你使用的是MySQL 5.1, 一定要使用InnoDB plugin,真的比舊版本的InnoDB要好很多。

InnoDB是一個很重要的儲存引擎,很多個人和公司都對其貢獻程式碼,而不僅僅是 Oracle公司的開發團隊。一些重要的貢獻者包括Google、Yasufumi Kinoshita、Percona,、Facebook等,他們的一些改進被直接移植到官方版本,也有一些由InnoDB團隊重新實現。 在過去的幾年間,InnoDB的改進速度大大加快,主要的改進集中在可測量性、可擴充套件性、 可配置化、效能、各種新特性和對Windows的支援等方面。MySQL 5.6實驗室預覽版 和里程碑版也包含了一系列重要的InnoDB新特性。

為改善InnoDB的效能,Oracle投入了大量的資源,並做了很多卓有成效的工作(外部貢獻者對此也提供了很大的幫助)。在本書的第二版中,我們注意到在超過四核CPU的系統中InnoDB表現不佳,而現在已經可以很好地擴充套件至24核的系統,甚至在某些場景, 32核或者更多核的系統中也表現良好。很多改進將在即將釋出的MySQL 5.6中引入, 當然也還有機會做更進一步的改善。

InnoDB概覽

InnoDB的資料儲存在表空間(tablespace)中,表空間是由InnoDB管理的一個黑盒子, 由一系列的資料檔案組成。在MySQL 4.1以後的版本中,InnoDB可以將每個表的資料 和索引存放在單獨的檔案中。InnoDB也可以使用裸裝置作為表空間的儲存介質,但現代的檔案系統使得裸裝置不再是必要的選擇。

InnoDB採用MVCC來支援高併發,並且實現了四個標準的隔離級別。其預設級別是 REPEATABLE READ (可重複讀),並且通過間隙鎖(next-key locking)策略防止幻讀的出現。 間隙鎖使得InnoDB不僅僅鎖定査詢涉及的行,還會對索引中的間隙進行鎖定,以防止幻影行的插入。 -

InnoDB表是基於聚簇索引建立的,我們會在後面的章節詳細討論聚簇索引。IimoDB的 索引結構和MySQL的其他儲存引擎有很大的不同,聚簇索引對主鍵査詢有很髙的效能。 不過它的二級索引(secondary index,非主鍵索引)中必須包含主鍵列,所以如果主鍵 列很大的話,其他的所有索引都會很大。因此,若表上的索引較多的話,主鍵應當儘可 能的小。InnoDB的儲存格式是平臺獨立的,也就是說可以將資料和索引檔案從Intel平 臺複製到PowerPC或者Sun SPARC平臺。

InnoDB內部做了很多優化,包括從磁碟讀取資料時釆用的可預測性預讀,能夠自動在 記憶體中建立hash索引以加速讀操作的自適應雜湊索引(adaptive hash index),以及能夠 加速插入操作的插入緩衝區(insert buffer)等。本書後面將更詳細地討論這些內容。

InnoDB的行為是非常複雜的,不容易理解。如果使用了 InnoDB引擎,筆者強烈建議閱 讀官方手冊中的"InnoDB事務模型和鎖” 一節。如果應用程式基於InnoDB構建,則事 先了解一下InnoDB的MVCC架構帶來的一些微妙和細節之處是非常有必要的。儲存引 擎要為所有使用者甚至包括修改資料的使用者維持一致性的檢視,是非常複雜的工作。

作為事務型的儲存引擎,InnoDB通過一些機制和工具支援真正的熱備份,Oracle提供 的MySQL Enterprise Backup. Percona提供的開源的XtraBackup都可以做到這一點。 MySQL的其他儲存引擎不支援熱備份,要獲取一致性檢視需要停止對所有表的寫入, 而在讀寫混合場景中,停止寫入可能也意味著停止讀取。

MylSAM儲存引擎

在MySQL 5.1及之前的版本,MylSAM是預設的儲存引擎。MylSAM提供了大量的特 性,包括全文索引、壓縮、空間函式(GIS)等,但MylSAM不支援事務和行級鎖,而且有一個毫無疑問的缺陷就是崩潰後無法安全恢復。正是由於MylSAM引擎的緣故,即 使MySQL支援事務已經很長時間了,在很多人的概念中MySQL還是非事務型的資料 庫。儘管MylSAM引擎不支援事務、不支援崩潰後的安全恢復,但它絕不是一無是處的。對於只讀的資料,或者表比較小、可以忍受修復(repair)操作,則依然可以繼續使 用MylSAM (但請不要預設使用MylSAM,而是應當預設使用InnoDB)。

儲存

MylSAM會將表儲存在兩個檔案中:資料檔案和索引檔案,分別以.MYD和.MYI為副檔名。MylSAM表可以包含動態或者靜態(長度固定)行。MySQL會根據表的定義來 決定採用何種行格式。MylSAM表可以儲存的行記錄數,一般受限於可用的磁碟空間, 或者作業系統中單個檔案的最大尺寸。

在MySQL 5.0中,MylSAM表如果是變長行,則預設配置只能處理256TB的資料,因 .為指向資料記錄的指標長度是6個位元組。而在更早的版本中,指標長度預設是4位元組,所以只能處理4GB的資料。而所有的MySQL版本都支援8位元組的指標。要改變 MylSAM表指標的長度(調高或者調低),可以通過修改表的MAX_R0WS和AVG_R0W_ LENGTH選項的值來實現,兩者相乘就是表可能達到的最大大小。修改這兩個引數會導致 重建整個表和表的所有索引,這可能需要很長的時間才能完成。

MylSAM特性

作為MySQL最早的儲存引擎之一,MylSAM有一些已經開發出來很多年的特性,可以 滿足使用者的實際需求。

加鎖與併發

MylSAM對整張表加鎖,而不是針對行。讀取時會對需要讀到的所有表加共享鎖, 寫入時則對錶加排他鎖。但是在表有讀取査詢的同時,也可以往表中插入新的記錄 (這被稱為併發插入,CONCURRENT INSERT) o

修復

對於MylSAM表,MySQL可以手工或者自動執行檢査和修復操作,但這裡說的修 復和事務.恢復以及崩潰恢復是不同的概念。執行表的修復可能導致一些資料丟失, 而且修復操作是非常慢的。可以通過CHECK TABLE mytable檢查表的錯誤,如果有 錯誤可以通過執行REPAIR TABLE mytable進行修復。另外,如果MySQL伺服器已 經關閉,也可以通過myisamchk命令列工具進行檢査和修復操作。

索引特性

對於MylSAM表,即使是BLOB和TEXT等長欄位,也可以基於其前500個字元建立

索引。MylSAM也支援全文索引,這是一種基於分詞建立的索引,可以支援複雜的 査詢。

延遲更新索引鍵(Delayed Key Write)

建立MylSAM表的時候,如果指定了 DELAY_KEY_WRITE選項,在每次修改執行完成 時,不會立刻將修改的索引資料寫入磁碟,而是會寫到記憶體中的鍵緩衝區(in.memory key buffer),只有在清理鍵緩衝區或者關閉表的時候才會將對應的索引塊寫入到磁 盤。這種方式可以極大地提升寫入效能,但是在資料庫或者主機崩潰時會造成索引 損壞,需要執行修復操作。延遲更新索引鍵的特性,可以在全域性設定,也可以為單 個表設定。

MylSAM壓縮表

如果表在建立並匯入資料以後,不會再進行修改操作,那麼這樣的表或許適合釆用- MylSAM壓縮表。

可以使用myisampack對MylSAM表進行壓縮(也叫打包pack)o壓縮表是不能進行修 改的(除非先將表解除壓縮,修改資料,然後再次壓縮)。壓縮表可以極大地減少磁碟 空間佔用,因此也可以減少磁碟I/O,從而提升査詢效能。壓縮表也支援索引,但索引 也是隻讀的。

以現在的硬體能力,對大多數應用場景,讀取壓縮表資料時的解壓帶來的開銷影響並不 大,而減少I/O帶來的好處則要大得多。壓縮時表中的記錄是獨立壓縮的,所以讀取單 行的時候不需要去解壓整個表(甚至也不解壓行所在的整個頁面)。

MylSAM效能

MylSAM引擎設計簡單,資料以緊密格式儲存,所以在某些場景下的效能很好。 MylSAM有一些伺服器級別的效能擴充套件限制,比如對索引鍵緩衝區(key cache)的 Mutex鎖,MariaDB基於段(segment)的索引鍵緩衝區機制來避免該問題。但MylSAM 最典型的效能問題還是表鎖的問題,如果你發現所有的査詢都長期處於“Locked”狀態, 那麼毫無疑問表鎖就是罪魁禍首。

MySQL內建的其他儲存引擎

MySQL還有一些有特殊用途的儲存引擎。在新版本中,有些可能因為一些原因已經不 再支援;另外還有些會繼續支援,但是需要明確地啟用後才能使用。

Archive 引擎

Archive儲存引擎只支援INSERT和SELECT操作,在MySQL 5.1之前也不支援索引。

Archive引擎會快取所有的寫並利用zlib對插入的行進行壓縮,所以比MylSAM表的磁 盤I/O更少。但是每次SELECT査詢都需要執行全表掃描。所以Archive表適合日誌和 資料釆集類應用,這類應用做資料分析時往往需要全表掃描。或者在一些需要更快速的 INSERT操作的場合下也可以使用。

Archive引擎支援行級鎖和專用的緩衝區,所以可以實現高併發的插入。在一個査詢開 始直到返回表中存在的所有行數之前,Archive引擎會阻止其他的SELECT執行,以實現 一致性讀。另外,也實現了批量插入在完成之前對讀操作是不可見的。這種機制模仿了 事務和MVCC的一些特性,但Archive引擎不是一個事務型的引擎,而是一個針對高速 插入和壓縮做了優化的簡單引擎。

Blackhole 引擎

Blackhole引擎沒有實現任何的儲存機制,它會丟棄所有插入的資料,不做任何儲存。但 是伺服器會記錄Blackhole表的日誌,所以可以用於複製資料到備庫,或者只是簡單地 記錄到日誌。這種特殊的儲存引擎可以在一些特殊的複製架構和日誌稽核時發揮作用。 但這種應用方式我們碰到過很多問題,因此並不推薦。

CSV引擎

CSV引擎可以將普通的CSV檔案(逗號分割值的檔案)作為MySQL的表來處理,但 這種表不支援索引。CSV引擎可以在資料庫執行時拷入或者拷出文件。可以將Excel 等電子表格軟體中的資料儲存為CSV檔案,然後複製到MySQL資料目錄下,就能在 MySQL中開啟使用。同樣,如果將資料寫入到一個CSV引擎表,其他的外部程式也能 立即從表的資料檔案中讀取csv格式的資料。因此CSV引擎可以作為一種資料交換的 機制,非常有用。

Federated 引擎

Federated引擎是訪問其他MySQL伺服器的一個代理,它會建立一個到遠端MySQL服 務器的客戶端連線,並將査詢傳輸到遠端伺服器執行,然後提取或者傳送需要的資料。 最初設計該儲存引擎是為了和企業級資料庫如Microsoft SQL Server和Oracle的類似特 性競爭的,可以說更多的是一種市場行為。儘管該引擎看起來提供了一種很好的跨服務 器的靈活性,但也經常帶來問題,因此預設是禁用的。MariaDB使用了它的一個後續改 進版本,叫做FederatedXo

Memory引擎

如果需要快速地訪問資料,並且這些資料不會被修改,重啟以後丟失也沒有關係,那麼 使用Memory表(以前也叫做HEAP表)是非常有用的。Memory表至少比MylSAM表 要快一個數量級,因為所有的資料都儲存在記憶體中,不需要進行磁碟I/O。Memory表的 結構在重啟以後還會保留,但資料會丟失。

Memroy表在很多場景可以發揮好的作用:

  • 用於査找(lookup)或者對映(mapping)表,例如將郵編和州名對映的表。

  • 用於快取週期性聚合資料(periodically aggregated data)的結果。

  • 用於儲存資料分析中產生的中間資料。

Memory表支援Hash索引,因此査找操作非常快。雖然Memory表的速度非常快,但還 是無法取代傳統的基於磁碟的表。Memroy表是表級鎖,因此併發寫入的效能較低。它 不支援BLOB或TEXT型別的列,並且每行的長度是固定的,所以即使指定了 VARCHAR列, 實際儲存時也會轉換成CHAR,這可能導致部分記憶體的浪費(其中一些限制在Percona版 本已經解決)。

如果MySQL在執行査詢的過程中需要使用臨時表來儲存中間結果,內部使用的臨時表 就是Memory表。如果中間結果太大超出了 Memory表的限制,或者含有BLOB或TEXT 欄位,則臨時表會轉換成MylSAM表。在後續的章節還會繼續討論該問題。

人們經常混淆Memory表和臨時表。臨時表是指使用CREATE TEMPORARY TABLE語句 建立的表,它可以使用任何儲存引擎,因此和Memory表不是一回事。臨時表只在 單個連線中可見,當連線斷開時,臨時表也將不復存在。

Merge引擎

Merge引擎是MylSAM引擎的一個變種。Merge表是由多個MylSAM表合併而來的虛 擬表。如果將MySQL用於日誌或者資料倉庫類應用,該引擎可以發揮作用。但是引入 分割槽功能後,該引擎已經被放棄(參考第7章)。

NDB叢集引擎

2003年,當時的MySQL AB公司從索尼愛立信公司收購了 NDB資料庫,然後開發了 NDB叢集儲存引擎,作為SQL和NDB原生協議之間的介面。MySQL伺服器、NDB集 群儲存引擎,以及分散式的、share.nothing的、容災的、高可用的NDB資料庫的組合, 被稱為MySQL叢集(MySQL Cluster)

第三方儲存引擎

OLTP類引擎等不多介紹了。