11、InnoDB存储引擎
InnoDB 是 MySQL 中第一個提供外鍵約束的存儲引擎,而且它對事務的處理能力是其它存儲引擎無法與之相比的。
MySQL 5.5 版本以后,默認存儲引擎由 MyISAM 修改為 InnoDB。InnoDB 是目前最重要、使用最廣泛的存儲引擎。
InnoDB 一直在持續(xù)改進,隨著處理能力的不斷提高,其優(yōu)秀的性能和可維護性使它成為生產中普遍推薦使用的存儲引擎。一般情況下,除非有特別的原因需要使用其它存儲引擎,否則應該優(yōu)先考慮 InnoDB 引擎。
下面從優(yōu)勢和物理存儲結構兩個方面來講解 InnoDB 存儲引擎。
InnoDB優(yōu)勢
InnoDB 之所以如此受寵,主要在于其功能方面的較多優(yōu)勢。
1)支持事務安裝
InnoDB 最重要的一點就是支持事務,可以說這是 InnoDB 成為 MySQL 中最流行的存儲引擎的一個非常重要的原因。InnoDB 還實現了 SQL92 標準所定義的 4 個隔離級別(READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ 和 SERIALIZABLE)。
InnoDB 對事務安全的支持,讓很多之前因為特殊業(yè)務而放棄使用 MySQL 的用戶轉向支持 MySQL。以及對數據庫選型持觀望態(tài)度的用戶來說,也大大增加了對 MySQL 的好感。
2)災難恢復性好
InnoDB 通過 commit、rollback、crash-recovery 來保障數據的安全。
具體來說,crash-recovery 就是指如果服務器因為硬件或軟件的問題而崩潰,不管當時數據是怎樣的狀態(tài),在重啟 MySQL 后,InnoDB 都會自動恢復到發(fā)生崩潰之前的狀態(tài),并回到用戶離開的地方。
3)使用行級鎖
InnoDB 改變了 MyISAM 的鎖機制,實現了行鎖。雖然 InnoDB 的行鎖機制是通過索引來完成的,但畢竟在數據庫中 99%的 SQL 語句都要使用索引來檢索數據。行鎖定機制也為 InnoDB 在承受高并發(fā)壓力的環(huán)境下增強了不小的競爭力。
在 SQL 查詢中可以自由地將 InnoDB 類型的表與其他類型的表混合起來,甚至在同一個查詢中也可以混合。
4)實現了緩沖處理
InnoDB 提供了專門的緩存池,實現了緩沖管理,不僅能緩沖索引也能緩沖數據,常用的數據可以直接從內存中處理,比從磁盤獲取數據處理速度要快。相比之下,MyISAM 只是緩存了索引。
InnoDB 的表和索引在一個邏輯表空間中,表空間可以包含數個文件(或原始磁盤分區(qū))。這與 MyISAM 表不同,比如在 MyISAM 表中每個表被保存在分離的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被限制為 2GB 的操作系統上。
5)支持外鍵
InnoDB 支持外鍵約束,檢查外鍵、插入、更新和刪除,以確保數據的完整性。在存儲表中數據時每張表的存儲都按主鍵順序存放,如果沒有顯式地在定義表時指定主鍵,InnoDB 會為每一行生成一個 6 字節(jié)的 ROWID ,并以此作為主鍵。
InnoDB 實現外鍵引用這一重要特性,使在數據庫端控制部分數據的完整性成為可能。雖然很多數據庫系統調優(yōu)專家都建議不要這樣做,但是對于不少用戶來說,大部分情況下,在數據庫端加外鍵控制仍然是成本最低的選擇。
6)適合需要大型數據庫的網站
InnoDB 被用在眾多需要高性能的大型數據庫網站上。
InnoDB 是為處理巨大數據量時的最大性能設計,它的 CPU 效率可能是任何其他基于磁盤的關系數據庫引擎所不能匹敵的。
除了以上幾個亮點之外,InnoDB 常常還有很多其它的功能特色帶給使用者驚喜。當然,使用 InnoDB 存儲引擎肯定也有缺點。相對于其它存儲引擎來說,使用 InnoDB 存儲引擎的讀寫效率稍差,且占用的數據空間相對較大。
物理存儲
使用 InnoDB 時,MySQL 會在數據目錄(Data)下創(chuàng)建一個名為 ibdata1 的 10MB 大小的自動擴展數據文件,以及兩個名為 ib_logfile0 和 ib_logfile1 的 5MB 大小的日志文件。
InnoDB 存儲引擎和 MyISAM 不太一樣,雖然也有 .frm 文件來存放表結構定義相關的元數據,但是表數據和索引數據是存放在一起的。至于是每個表單獨存放還是所有表存放在一起,用戶可以自己設置(下面會介紹如何設置)。
InnoDB 的物理存儲結構分為兩大部分:
1. 數據文件(表數據和索引數據)
數據文件用來存放數據表中的數據和所有的索引數據,包括主鍵和其他普通索引。
InnoDB 存儲的數據采用表空間(Tablepace)進行存放設計。表空間是用來存放 MySQL 系統相關信息的一個特殊共享表空間。
InnoDB 的表空間分為以下兩種形式:
- 共享表空間,表數據和索引都存放在同一個表空間。默認的表空間文件就是上面所提到的 MySQL 初始化路徑下的 ibdata1 文件。
- 獨立表空間,每個表的數據和索引被存放在一個單獨的 .ibd 文件中。
可以通過以下命令查看 MySQL 是否使用獨立表空間:
mysql> SHOW VARIABLES LIKE 'innodb_file_per_table%'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | ON | +-----------------------+-------+ 1 row in set, 1 warning (0.01 sec)innodb_file_per_table 值為 ON 時表示開啟獨立表文件,InnoDB 表的數據和索引都會以單獨的形式存放;
值為 OFF 時,InnoDB 表的數據和索引都存放在一個表空間。可以通過設置該參數的值來決定是否使用獨立表空間,具體設置文章后面會講解。
1)共享表空間
共享表空間的數據文件可以設置為固定大小和可自動擴展大小兩種形式。自動擴展形式的文件可以設置文件的最大大小和每次擴展量。在創(chuàng)建自動擴展的數據文件時,建議大家最好加上最大尺寸的屬性,一個原因是文件系統本身有一定的大小限制,還有一個原因就是方便自身維護。
當表空間快要用完的時候,我們必須要為其增加數據文件,當然,只有共享表空間有此操作。
共享表空間增加數據文件的操作比較簡單,只需要在 innodb_data_file_path 參數后面按照標準格式設置好文件路徑和相關屬性即可。
innodb_data_file_path 參數負責定義共享表空間的路徑、初始化大小、自動擴展策略。可以使用以下命令查看當前共享表空間文件的路徑、大小和自動化策略:
mysql> SHOW VARIABLES LIKE 'innodb_data_file_path%'; +-----------------------+------------------------+ | Variable_name | Value | +-----------------------+------------------------+ | innodb_data_file_path | ibdata1:12M:autoextend | +-----------------------+------------------------+ 1 row in set, 1 warning (0.01 sec)用戶可以通過 innodb_data_file_path 參數來指定表空間文件,格式如下:
innodb_data_file_path=datafile_spec1[;datafile_spec2]...其中,datafile_spec1 格式為表空間文件路徑:大小:屬性,還可以指定多個文件組成一個表空間,同時指定文件的屬性,例如:
[mysqld] innodb_data_file_path=/db/ibdata1:2000M;/dr2/db/ibdata2:2000M:autoextend這里將 /db/ibdata1 和 /dr2/db/ibdata2 兩個文件用來組成表空間。若這兩個文件位于不同的磁盤上,磁盤的負載可能被平均,因此可以提高數據庫的整體性能。
指定多個文件時,autoextend 屬性只在最后一個數據文件中指定,表示表空間自動擴展。這里表示文件 ibdata1 的大小為 2000MB,文件 ibdata2 的大小為 2000MB,如果用完了 2000MB,該文件還可以自動增長。
設置完 innodb_data_file_path 參數后,所有基于 InnoDB 存儲引擎的表的數據都會記錄到該共享表空間中。
不過這里需要注意的是,InnoDB 在創(chuàng)建新數據文件時不會創(chuàng)建目錄,如果指定目錄不存在,則會報錯并無法啟動。另外,InnoDB 給共享表空間增加數據文件之后,必須要重啟數據庫系統才能生效。
這也是大多數人一直不太喜歡使用共享表空間而選用獨立表空間的原因之一。
2)獨立表空間
通過設置 innodb_file_per_table 參數,可以將每個基于 InnoDB 存儲引擎的表產生一個獨立表空間。
獨立表空間的命名規(guī)則為表名.ibd。通過這樣的方式,用戶不用將所有數據都存放于默認的表空間中。
使用 SET 命令打開/關閉獨立表空間,命令和運行結果如下:
mysql> SET GLOBAL innodb_file_per_table=1; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE 'innodb_file_per_table'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | ON | +-----------------------+-------+ 1 row in set, 1 warning (0.03 sec) mysql> SET GLOBAL innodb_file_per_table=0; Query OK, 0 rows affected (0.00 sec)mysql> SHOW VARIABLES LIKE 'innodb_file_per_table'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | OFF | +-----------------------+-------+ 1 row in set, 1 warning (0.00 sec)需要注意的是,單獨的表空間文件只存儲該表的數據、索引和緩沖等信息。所以無論是使用共享表空間還是獨享表空間來存放表,共享表空間都是必須存在的。
2. 日志文件
默認情況下,InnoDB 存儲引擎的數據目錄下會有兩個名為 ib_logfile0 和 ib_logfile1 的文件。在 MySQL 官方手冊中將其稱為 InnoDB 存儲引擎的重做日志文件(redo log file)。
重做日志文件對 InnoDB 存儲引擎至關重要。InnoDB 可以通過重做日志將數據庫宕機時已經完成但還沒有來得及將數據寫入磁盤的事務恢復,也能將所有部分完成并已經寫入磁盤的未完成事務回滾,并且將數據還原,以此來保證數據的完整性。
每個 InnoDB 存儲引擎至少有 1 個重做日志文件組(group),每個文件組下至少有 2 個重做日志文件,如默認的 ib_logfile0 和 ib_logfile1。
如果你的數據庫中有 InnoDB 的表,那么千萬別全部刪除 InnoDB 的日志文件,這很可能會讓你的數據庫 Crash,無法啟動,或者丟失數據。
數據庫不工作或停止響應、進程中斷等情況,在業(yè)界也叫做數據庫 Crash。
在 MySQL 啟動參數文件設置中,InnoDB 的所有參數基本上都帶有前綴“innodb_”,不論是 InnoDB 數據還是和日志相關,或者是其他一些性能,事務等等相關的參數都是一樣。
下面是影響重做日志文件的參數:
- innodb_log_file_size:指定每個重做日志的大小。
- innodb_log_files_in_group:指定日志文件組中重做日志文件的數量,默認為 1。
- innodb_mirrored_log_groups:指定日志鏡像文件組的數量,默認為 1。
- innodb_log_group_home_dir:指定日志文件組所在路徑,默認為 ./。
簡而言之,MySQL 中所有和 InnoDB 相關的系統變量都以“innodb_”做為前綴。
拓展
在 MySQL 中,可以通過 skip-innodb 參數來屏蔽 InnoDB 存儲引擎,這樣即使我們在安裝編譯時,安裝了 InnoDB 存儲引擎,使用者也無法創(chuàng)建 InnoDB 的表。
總結
以上是生活随笔為你收集整理的11、InnoDB存储引擎的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 10、MySQL存储引擎有哪些?
- 下一篇: 12、MyISAM存储引擎