MySQL的基本體系和架構介紹

你好,我是idea。
本文是該專欄的第一篇文章,主要是聊聊關於MySQL的整體架構和它的一些背景介紹。之所以我把這一講的內容放在了第一篇,是因爲我認爲對於數據庫的理解和學習應該是先從總體入手,再到細微的部分深入挖掘,這樣的學習過程會給自己留下更加深入的印象。

相信在大部分的程序員在工作中都有接觸過MySQL這款數據庫,在MySQL的官網上邊,你會看到這樣的一段介紹內容:
在這裏插入圖片描述
大致翻譯過來的意思就是說:
MySQL是世界上最受歡迎的開源數據庫。無論您是快速增長的Web資產,技術ISV還是大型企業,MySQL都能經濟高效地幫助您交付高性能,可擴展的數據庫應用程序。
這款開源的數據庫,其源碼在github上邊的地址爲:https://github.com/mysql/mysql-server star還是挺多的。
那麼既然是一款公認好用的開源數據庫,我們是否應該對它進行一個深入的瞭解呢?

下邊我畫了一個大致的MySQL基本架構圖
在這裏插入圖片描述
客戶端
MySQL的整體結構可以分成2個大模塊,分別是客戶端和服務端。這裏頭說的客戶端是指提供連接MySQL的工具集合,常見的客戶端工具有mysql client,mysqladmin,mysqldump,mysqlcheck,mysqlimport,mysqlshow等等。MySQL數據庫本身提供的連接方式包含有多種,其中最常見的就是基於TCP/IP協議進行連接了。基礎的命令內容爲:

mysql -h [地址] -u [用戶名] -p [密碼]

在安裝完畢了MySQL數據庫之後,我們會發現數據庫自身已經幫我們預先設置了一個名字叫做mysql的數據庫,每次獲取鏈接的時候就會到該庫裏面的User表檢索賬號信息以及相關的權限。

在Linux系統中,有很多進程間通信方式,套接字(Socket)就是其中的一種。但傳統的套接字的用法都是基於TCP/IP協議棧的,需要指定IP地址。如果不同主機上的兩個進程進行通信,當然這樣做沒什麼問題。但是,如果只需要在一臺機器上的兩個不同進程間通信,還要用到IP地址就有點大材小用了。

MySQL數據庫自身是支持UNIX域套接字進行通信的,因此在MySQL的文件目錄下邊會有這麼一份文件:mysql.sock。
這份文件主要是通過Unix域套接字供我們將本地連接數據庫服務器使用。
以前筆者就遇到過sock文件被修改,導致連接數據庫異常的情況,例如mysql的log中出現這種報錯記錄:

Could not create unix socket lock file

如果sock文件丟失的話,可以重新創建一份sock文件進行通信。

服務端
每次客戶端想要鏈接到服務端都需要從服務端的連接池獲取相應的連接。假設我們每次連接都需要完成 構建鏈接,當我們獲取到了鏈接之後,在mysql的server端可以通過這樣一個命令來對每個鏈接的狀態進行查看:

mysql> show processList;
+----+-------------+-----------+------+---------+--------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time   | State                                                  | Info             |
+----+-------------+-----------+------+---------+--------+--------------------------------------------------------+------------------+
|  2 | system user |           | NULL | Connect | 195290 | Waiting for master to send event                       | NULL             |
|  3 | system user |           | NULL | Connect |    257 | Slave has read all relay log; waiting for more updates | NULL             |
| 19 | root        | localhost | NULL | Query   |      0 | starting                                               | show processList |
+----+-------------+-----------+------+---------+--------+--------------------------------------------------------+------------------+
3 rows in set (0.01 sec)

注意通過show process List命令我們一般也只能夠查看到當前登錄用戶的連接情況。在這方面mysql是會有權限區分的。
mysql的information_schema 系統庫裏面的processlist 表記錄了關於數據庫連接數的信息,可以通過查看這張表來分析連接數的問題。
processlist表的基本結構如下:

CREATE TEMPORARY TABLE `PROCESSLIST` (
  `ID` bigint(21) unsigned NOT NULL DEFAULT '0',
  `USER` varchar(32) NOT NULL DEFAULT '',
  `HOST` varchar(64) NOT NULL DEFAULT '',
  `DB` varchar(64) DEFAULT NULL,
  `COMMAND` varchar(16) NOT NULL DEFAULT '',
  `TIME` int(7) NOT NULL DEFAULT '0',
  `STATE` varchar(64) DEFAULT NULL,
  `INFO` longtext
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

這裏面的幾個參數大概講解一下:
USER 是指當前連接數據庫所用的賬號信息,在實際的業務場景中,連接的賬號可能是業務服務器發送的連接,也有可能是從庫的連接;有個特殊的名稱叫做system user 賬號,這個鏈接是由服務器產生的非客戶端線程。
Host 這個參數是指鏈接的客戶端主機名。
db 這個標識鏈接的數據庫
Command 標識該線程正在執行的命令,通常都是會有對應的ddl或者dml語句。
Time 表示線程處於當前狀態的時間長短,線程當前時間的概念在某些情況下可能會發生改變:線程可以改變時間。對於正在從主機處理事件的從站上運行的線程,線程時間設置爲事件中發現的時間,因此反映了主站而不是從站的當前時間。SET TIMESTAMP = value。
State 對應Command指令,大多數狀態對應於非常快速的操作。如果線程在給定狀態下保持多秒,則可能存在需要調查的問題。
Info 包含由線程執行的語句的文本或者NULL,如果它不是執行的話。默認情況下,此值僅包含語句的前100個字符。要查看完整的語句,請使用SHOW FULL PROCESSLIST。

查詢緩存
對於一些數據修改變動比較少的表,MySQL內部提供了一套叫做Query Cache的緩存池來進行存儲。MySQL可以通過以下命令來查看內部的查詢緩存參數值:

mysql> show variables like '%query_cache%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| have_query_cache             | YES     |
| query_cache_limit            | 1048576 |
| query_cache_min_res_unit     | 4096    |
| query_cache_size             | 1048576 |
| query_cache_type             | OFF     |
| query_cache_wlock_invalidate | OFF     |
+------------------------------+---------+
6 rows in set (0.00 sec)

關於查詢緩存的功能,在MySQL中是根據sql語句來做緩存檢索的,默認情況下該緩存屬性是關閉的,對於更新頻率較高的表而言,設置查詢緩存其實本身的命中率並不高,因此該功能MySQL也並不提倡使用,在MySQL8.0的時候該功能也被移除了。

語法分析器
接下來便是語法分析環節了,該模塊主要是對傳入的SQL語句內容做一些語法內容的校驗,例如判斷該語句是屬於DQL還是DML等類型。

優化器
有時候你會發現,執行的一條SQL可能並不會按照預期的方式來走索引,這是因爲MySQL內部有優化器這麼一個角色的存在。當然索引的選擇只是優化器的其中一項特點,優化器的目的就是通過一定的邏輯判斷,將sql執行的效率發揮到最高效化。

執行器
當Sql準備好了,優化結束了,執行器便會發起sql請求引擎層的接口,這個環節中,執行器還回去判斷當前請求的會話是否有權限執行相關的SQL語句。

存儲引擎
可以說整個數據庫的核心部分就是存儲引擎環節了,不同的存儲引擎對數據的存儲結構和算法設計方便都有着巨大的差別,而且不同的存儲引擎專門爲不同的應用場景所設計。目前我們主流的存儲引擎有Innodb,MyISAM,Memory,等
通過下邊的這條命令我們可以看到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)

關於MySQL的整體架構介紹大概到這裏就先暫時告一段落了,下一篇文章我會講解一些關於存儲引擎的比對問題。

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