MySQL是什么?它的架構是怎樣的?假如讓你重新設計,你要怎么做?
重生
當我醒來睜開眼睛的時候,我看到辦公桌的電腦長這個樣子。
啥情況,我猝死了還是穿越了?還在我一臉懵逼的時候……
系統(tǒng)提示:蕭劍臣,你已經 dead 過一次了,現在在另一個世界獲得重生,你需要在這個世界完成一個任務,設計一款數據庫 MySQL,就能就能回到原來的世界,迎娶白富美,脫離 996,并且在這個世界的成就也能帶回原來的世界。
打開這個電腦一看,時間是 1979 年。那時 Bill Gates 退學沒多久,微軟公司也才剛剛起步,世間還沒有 996 和福報,沒有過勞猝死……
這個狗血,我居然重生了,我的機會來了……
1990 年,我接到了一個項目,客戶需要為當時的 UNIREG 提供更加通用的 SQL 接口,公司的另一個團隊負責人「郝紀曉」提議直接使用商用數據庫。
重生后的第一個副本出現了,我不能讓「郝紀曉」的提議達成,否則將永遠 「狗 dead」。
經過一番測試后,我發(fā)現商用數據庫的速度并不盡如人意,無法滿足客戶的需求。于是我聯(lián)合 Monty Widenius,他雄心大起,設計一個數據庫的任務就此開始……
MySQL 架構設計
腦子里有 MySQL 8.0 版本的架構設計思路,我在這里豈不是如魚得水,起飛,起飛,必須起飛。于是我把 MySQL 的架構設計圖畫了出來,如圖 1-1 所示。
圖片
看到如此層級的架構設計,分層明確,職責清晰,眾人驚呆了!!
但郝紀曉不懈的說到:劃分這么多層,有什么意義?該不會是脫褲子放屁多此一舉吧。
我心想,難道這是副第一個關卡出現的一個 boss,我看了看他的工牌,上面寫著資深架構師——郝紀曉。
系統(tǒng)提示音:新手任務,畫出 MySQL 系統(tǒng)架構設計圖,并解釋每一層以及每層組件的主要作用,讓眾人理解并清晰認識該架構,讓大家按照此架構開發(fā)。
好家伙,這個任務難度不大,我自信的給眾人解釋到:這個數據庫名叫 MySQL,至上而下一共分為四層,重點是 Server 服務層和存儲引擎層。
客戶端由不同語言開發(fā)的客戶端,Server 層包括連接池、安全管理、線程管理、緩存、SQL 接口、解析器、優(yōu)化器等,涵蓋了 MySQL 的大多數核心功能。
而存儲引擎層負責數據的存儲的讀取。這是一個插件式架構,支持 InnoDB、MyISAM、Memory 等多個存儲引擎。
客戶端 Client
這是一個 CS 架構,支持各種語言的客戶端連接器連接到數據庫,比如 Java、C++、JDBC 等。同時也支持 Shell 腳本直接連接。
Server 服務層
這一層至關重要,里面還還會劃分為「連接與安全管理」和「SQL 解析和優(yōu)化」兩大模塊。
服務層是 MySQL 中的核心組件,負責提供各種數據庫操作所需的基本功能,如 SQL 語法處理、事務管理、鎖管理等。
連接與安全管理
當客戶端發(fā)送連接請求時,MySQL 服務器會在連接與安全管理接收請求,分配一個線程來處理該連接,隨后進行身份驗證。具體的功能如下:
- 當客戶端發(fā)起連接請求時,MySQL 會創(chuàng)建一個專用的線程(以操作系統(tǒng)級別的線程實現)來為該客戶端服務。
- MYSQL 對 TCP 傳輸過來的賬號密碼做身份認證、權限獲?。ɡ?,是否允許客戶端對 world 數據庫中的 Country 表執(zhí)行 SELECT 語句)。驗證通過,查詢賬戶擁有的權限,并緩存起來。此鏈接是一個長鏈接
- 對于 TCP 鏈接,MySQL 采用池化技術,節(jié)省了 TCP 鏈接創(chuàng)建和銷毀的成本。
- 一個客戶端請求,必須要分配一個線程專門與客戶端進行交互,所以還有個線程池,每一個鏈接從線程池中獲取一個線程,省去了創(chuàng)建和銷毀線程的開銷。把線程池占滿了,再連就報連接滿了。
SQL 解析和優(yōu)化
SQL Interface(SQL 接口,用來接受用戶的 SQL 命令,并返回需要的結果。比如 select from 就是調用 SQL Interface。
Parse 解析器
MySQL 解析查詢以創(chuàng)建內部數據結構(解析樹),然后對其進行各種優(yōu)化,包括重寫查詢、決定表的讀取順序,以及選擇合適的索引等。
Optimizer 優(yōu)化器
通過語法解析,MySQL 知道你的真實意圖了,但你寫的 SQL 不一定是高效的。
查詢之前會使用查詢優(yōu)化器確定 SQL 語句的執(zhí)行路徑,生成一個執(zhí)行計劃,這個執(zhí)行計劃表明使用哪些索引進行查詢。
Caches & Buffers 緩沖區(qū)
MySQL 內部維持著一些 Cache 和 Buffer,這個緩存機制是由一系列小緩存組成的。比如表緩存,記錄緩存,key 緩存,權限緩存等。這個查詢緩存可以在 不同客戶端之間共享。
- 查詢緩存:當相同的 SQL 查詢被多次執(zhí)行時,可以從查詢緩存中直接獲取結果,提高性能。由于 MySQL 8.0 中已移除了查詢緩存功能,使用者需要自行實現相關功能,如使用 Redis、Memcached 等中間緩存系統(tǒng)。
- 表緩存:用于存儲表的元數據,如表的結構定義。當查詢需要表信息時,優(yōu)先從表緩存中獲取,避免磁盤操作。
- 線程緩存:用于復用服務器的連接線程。當一個連接關閉后,它的線程會被放回線程緩存池中,供新的連接使用。線程池意味著減少了創(chuàng)建和銷毀線程的開銷。
- 緩沖池:主要用于 InnoDB 存儲引擎,緩沖池管理緩存的數據頁,包括數據和索引。當需要訪問這些頁時,可以直接從緩沖池讀取,提高訪問速度。
buffer 與 cache 的區(qū)別?
簡單的說就是,buffer 是寫緩存,cache 是讀緩存。
存儲引擎層
存儲引擎層負責存儲數據和執(zhí)行 SQL 語句。MySQL 支持多種存儲引擎,每種引擎各有特點,根據實際需求進行選用。當然,只要沒有非常明確的特殊需求就不需要更改存儲引擎,因為 InnoDB 在大部分場景下都比其他引擎更加適用。
InnoDB:InnoDB 是 MySQL 的默認存儲引擎,提供了事務支持、行級鎖定、外鍵約束等功能,主要用于高并發(fā)、高可靠性的 OLTP 場景。
MyISAM:MyISAM 通常用于只讀數據表,適用于簡單查詢和全文索引。其不支持事務、行級鎖等功能,適用于 OLAP 場景。
Memory:Memory 存儲引擎支持哈希和 B 樹索引,它將數據存儲在內存中,易受到系統(tǒng)斷電或宕機等影響,具有較高的寫性能但不適用于大規(guī)模數據分布。
其他存儲引擎:MySQL 還支持如 Archive、NDB Cluster 等其他存儲引擎,它們分別適用于存檔表、分布式數據庫等不同場景。
我們可以在 SQL 命令行中執(zhí)行 show engines; 來查看當前支持的存儲引擎:
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)文件系統(tǒng)層
文件系統(tǒng)由各操作系統(tǒng)提供,MySQL 將其持久化的數據物理存儲在磁盤上,持久化保存數據、索引、binlog、redo log、undo log、error 日志、慢 sql 等;
總結
- 服務層的連接和安全管理:用戶與 MYSQL 服務進行 TCP 鏈接,校驗用戶身份,用戶權限。
- 服務層的 SQL 解析和優(yōu)化:用戶寫的 SQL 語句會到服務層進行解析,生成語法樹。優(yōu)化 SQL 語句,生成執(zhí)行計劃。
- 引擎層:真正與磁盤進行交互,對數據進行存儲和讀取。
最后,我再附上一張在我原來的世界尤其盛行的架構圖,與 圖 1-1 最大的差別是這次用英文,如圖 1-2 所示。
圖片
我說完之后,眾人紛紛對我稱贊。CTO 覺得我的架構設計考慮的太周全了,立馬從 T3 晉升為 T4,薪資漲了 20%……
故事還沒結束,結構圖出來以后,郝紀曉說道:架構圖雖然不錯,可是還有很多問題并沒提及,我們是實干主義,不是寫個架構圖就能忽悠的。
- 一條查詢、insert、update、delete 語句的執(zhí)行流程是怎樣的?
- 并發(fā)如何控制?
- 事務如何處理?
- Server 層與存儲引擎層之間如何保證故障恢復?
- binlog、redo log、undo log 都是什么玩意?
- 磁盤很慢,如何將 讀寫的隨機 I/O 操作變成順序寫保證 數據庫性能?
























