01-MySQL體系結構與存儲引擎
MySQL 被設計為一個可移植的數據庫,幾乎在當前所有系統上都能運行。盡管各平臺在底層實現方面都各有不同,但是 MySQL 基本上能保證在各平臺上的物理體系結構的一致性。
1. 定義數據庫和實例
在數據庫領域中有兩個詞很容易混淆:“數據庫”(database) 和 “實例”(instance),這兩個術語的定義如下。
- 數據庫:物理操作系統文件或其他形式文件類型的集合。
- 實例:數據庫實例由後臺線程以及一個共享內存區組成。
數據庫是文件的集合,是依照某種數據模型組織起來並存放於二級存儲器中的數據集合;數據庫實例是程序,是位於用戶和操作系統之間的一層數據管理軟件。用戶或應用程序對數據庫的任何操作,都必須通過數據庫實例進行。
MySQL 被設計為一個單進程多線程架構的數據庫,也就是說 MySQL 數據庫實例在操作系統上的表現就是一個進程。
當啟動實例時,MySQL 數據庫會去讀取配置文件,根據配置文件中的參數來啟動數據庫實例。通過如下命令可以查看當 MySQL 數據庫實例啟動時,會去哪些位置查找配置文件。
localhost:~ xukun06$ mysql --help | grep my.cnf order of preference, my.cnf, $MYSQL_TCP_PORT, /etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf
如果沒有配置文件,MySQL 會按照編譯時的默認參數設置啟動實例。
如果多個配置文件中出現同一個參數,MySQL 會以讀取到的最後一個配置文件的參數為準。
2. MySQL 體系結構
從圖中可見,MySQL 由以下幾部分組成:
- 連接池組件
- 管理服務和工具組建
- SQL接口組件
- 查詢分析器組件
- 優化器組件
- 緩沖組件
- 插件式存儲引擎
- 物理文件
MySQL 數據庫區別於其他數據庫的最重要的一個特點就是其插件式的存儲引擎。需要註意的是,存儲引擎是基於表的,而不是數據庫。
3. MySQL 邏輯架構
MySQL 邏輯架構主要分為如下三層:
- 服務層:完成連接處理、授權認證和安全認證等功能。
- 核心層:進行查詢的解析、分析、優化和緩存;處理內置函數;所有跨存儲引擎的功能都在這一層完成,比如視圖、存儲過程和觸發器等。
- 引擎層:負責數據的存取和事務的處理。
在解析查詢之前,如果查詢緩存是打開的,會先判斷這個查詢是否命中緩存,如果命中緩存則直接返回緩存的結果。這種情況下查詢不會被解析,也不會生成執行計劃,更不會被執行。
所謂的”查詢緩存“,可以理解為一個類似於 HashMap 的數據結構,key 是根據查詢本身、目標數據庫、客戶端協議版本號以及其他一些可能會影響查詢結果的元素計算得來,value 是該查詢的結果。所以,兩個查詢有任何字符的不同,包括空格和註釋,都會導致緩存沒有命中。另外,如果查詢中含有自定義函數、時間、用戶變量或臨時表等,這種查詢都不會被緩存,因為這些查詢會因為不同用戶或在不同時間執行得到不同的結果。比如查詢中包含 NOW() 函數。
當表的數據或結構發生變化,和這張表相關的查詢緩存都會失效。所以,如果查詢緩存比較大或碎片較多,將緩存置為失效的操作會帶來很大的性能開銷。因此,對於寫密集型應用來說,不建議開啟查詢緩存。
4. MySQL 存儲引擎
插件式存儲引擎是 MySQL 區別於其他數據庫的一個最重要特性。存儲引擎的好處是:每個存儲引擎都有各自的特點,能夠根據具體的應用建立不同的存儲引擎表。
通過如下命令可以查看當前 MySQL 數據庫支持哪些存儲引擎。
mysql> show engines; +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | MyISAM | YES | MyISAM storage engine | NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO | | FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ 9 rows in set (0.00 sec)
4.1 InnoDB 存儲引擎
InnoDB 存儲引擎支持事務,設計目標主要面向在線事務處理(OLTP)應用,特點是行鎖設計、支持外鍵,並支持類似於 oracle 的非鎖定讀,即默認讀取操作不會產生鎖。從 MySQL 5.5.8 版本開始,InnoDB 存儲引擎是默認的存儲引擎。
InnoDB 存儲引擎將數據放在一個邏輯的表空間中,這個空間像黑盒一樣由 InnoDB 存儲引擎自身進行管理。從 MySQL 4.1 版本開始,可以將每個 InnoDB 存儲引擎的表單獨存放到一個獨立的 ibd 文件中。
InnoDB 通過使用多版本並發控制(MVCC)來獲得高並發性,並且實現了 SQL 標準的四種隔離級別,默認是 REPEATABLE 級別。同時,使用一種被稱為 next-key locking 的策略避免幻讀。此外,InnoDB 存儲引擎會提供了插入緩沖、二次寫、自適應哈希索引和預讀等高性能和高可用的特性。
對表中數據的存儲,InnoDB 存儲引擎采用了“聚集”的方式,每張表的存儲都是按主鍵邏輯順序進行存放。如果在表定義時沒有指定主鍵,InnoDB 存儲引擎會為每一行生成一個不可見的 6 字節的 ROWID,並以此作為主鍵。
4.2 MyISAM 存儲引擎
MyISAM 存儲引擎不支持事務,表鎖設計,支持全文索引,主要面向一些 OLAP 數據庫應用。
MyISAM 存儲引擎表中,frm 文件存儲表定義,MYD 存放數據文件,MYI 存放索引文件。
MyISAM 存儲引擎的緩沖池只緩存索引文件,不緩沖數據文件,這點和其他大多數使用 LRU 算法緩存數據的數據庫大不相同。數據文件的緩存交由操作系統本身來完成。
4.3 InnoDB vs MyISAM
MyISAM | InnoDB | |
數據文件 | frm + MYD +MYI | ibd |
緩存 | 只緩存索引文件 | 緩存索引和數據 |
事務 | 不支持 | 支持 |
外鍵 | 不支持 | 支持 |
支持的索引 |
|
|
鎖 | 表鎖 | 行鎖 |
對索引進行壓縮 | 不壓縮 | |
select * from table | 返回保存的行數 | 全表掃描返回行數 |
delete from table | 重新建表 | 一行一行刪除 |
01-MySQL體系結構與存儲引擎