MySQL 原理篇
MySQL 體系結構
MySQL 體系結構圖:
MySQL 從概念上分為四層,這四層自頂向下分別是網絡連接層,服務層(核心層),存儲引擎層,系統文件層。我們自頂向下開始講解。
網絡連接層(Client Connectors)
主要負責連接管理、授權認證、安全等等。每個客戶端連接都對應着服務器上的一個線程。服務器上維護了一個線程池,避免為每個連接都創建銷毀一個線程。當客戶端連接到 MySQL 服務器時,服務器對其進行認證。可以通過用戶名與密碼認證,也可以通過 SSL 證書進行認證。登錄認證后,服務器還會驗證客戶端是否有執行某個查詢的操作權限。這一層並不是 MySQL 所特有的技術。
服務層(MySQL SERVER)
第二層服務層是 MySQL 的核心,MySQL 的核心服務層都在這一層,查詢解析,SQL 執行計划分析,SQL 執行計划優化,查詢緩存。以及跨存儲引擎的功能都在這一層實現:存儲過程,觸發器,視圖等。
- 連接池(Connection Pool):管理、緩沖用戶的連接,線程處理等需要緩存的需求
- 管理服務和工具組件(Services & utilities):系統管理和控制工具,例如備份恢復、MySQL 復制、集群等
- SQL 接口(SQL Interface):接受用戶的 SQL 命令,並且返回用戶需要查詢的結果
- 查詢解析器(Parser):SQL 命令傳遞到解析器的時候會被解析器驗證和解析(權限、語法結構)
- 查詢優化器(Optimizer):SQL 語句在查詢之前會使用查詢優化器對查詢進行優化
- 緩存(Caches):如果查詢緩存有命中的查詢結果,查詢語句就可以直接去查詢緩存中取數據
存儲引擎層(Pluggable Storage Engines)
負責 MySQL 中數據的存儲與提取。 服務器中的查詢執行引擎通過 API 與存儲引擎進行通信,通過接口屏蔽了不同存儲引擎之間的差異。MySQL 采用插件式的存儲引擎。MySQL 為我們提供了許多存儲引擎,每種存儲引擎有不同的特點。我們可以根據不同的業務特點,選擇最適合的存儲引擎。如果對於存儲引擎的性能不滿意,可以通過修改源碼來得到自己想要達到的性能。
各個存儲引擎的描述參考下文。
特點:
- MySQL 采用插件式的存儲引擎。
- 存儲引擎是針對於表的而不是針對庫的(一個庫中不同表可以使用不同的存儲引擎),服務器通過 API 與存儲引擎進行通信,用來屏蔽不同存儲引擎之間的差異。
- 不管表采用什么樣的存儲引擎,都會在數據區,產生對應的一個 的一個 frm 文件(表結構定義描述文件)
系統文件層(File System NTFS ext4 SAN NAS)
文件系統,數據、日志(redo,undo)、索引、錯誤日志、查詢記錄、慢查詢等,詳細參考下文的物理文件描述。
比如該層將數據庫的數據存儲在文件系統之上,並完成與存儲引擎的交互。在 MySQL 索引機制 中有講到 Myisam 和 InnoDB 的文件結構內容。
MySQL 存儲引擎
下面簡單介紹一下 MySQL 中常見的的存儲引擎
CSV 存儲引擎
數據存儲以 CSV 文件。
特點:
- 不能定義索引、列定義必須為 NOT NULL、不能設置自增列, 不適用大表或者數據的在線處理
- CSV 數據的存儲用逗號隔開,可直接編輯 CSV 文件進行數據的編排,數據安全性低。編輯之后,要生效使用
flush table XXX
命令
應用場景:
- 數據的快速導出導入
- 表格直接轉換成 表格直接轉換成 CSV
Archive 存儲引擎
壓縮協議進行數據的存儲,數據存儲為 ARZ 文件格式。
特點:
- 只支持 insert 和 select 兩種操作
- 只允許自增 ID 列建立索引
- 行級鎖
- 不支持事務
- 數據占用磁盤少
應用場景:
- 日志系統
- 大量的設備數據采集
Memory 存儲引擎
數據都是存儲在內存中,IO 效率要比其他引擎高很多,服務重啟數據會丟失,內存數據表默認只有 16M,一般我們不會使用到 Memory 存儲引擎。
特點:
- 支持 hash 索引,B tree 索引,默認 hash(查找復雜度 0(1))
- 字段長度都是固定長度 varchar(32)=char(32)
- 不支持大數據存儲類型字段如 blog,text
- 表級鎖
應用場景:
- 等值查找熱度較高數據
- 在排序、分組等操作中,當數據量小於16M(默認大小),由查詢優化器建立的臨時表就是 Memory 類型
MyISAM 存儲引擎
MySQL5.5 版本之前的默認存儲引擎,較多的系統表也還是使用這個存儲引擎,系統臨時表也會用到 MyISAM 存儲引擎。
特點:
- select count(*) from table 無需進行數據的掃描
- 數據(MYD)和索引(MYI)分開存儲
- 表級鎖
- 不支持事務
應用場景:
- 在排序、分組等操作中,當數量超過一定大小之后,由查詢優化器建立的臨時表就是 MyISAM 類型
- 報表,數據倉庫
InnoDB 存儲引擎
MySQL 5.5 及以后版本的默認存儲引擎。
特點:
- 事務 ACID
- 行級鎖
- 聚集索引(主鍵索引)方式進行數據存儲
- 支持外鍵關系保證數據完整性
對比
Feature | MyISAM | Memory | InnoDB | Archive | NDB |
B-tree indexes | Yes | Yes | Yes | No | No |
Backup/point-in-time recovery(note 1) | Yes | Yes | Yes | Yes | Yes |
Cluster database support | No | No | No | No | Yes |
Clustered indexes | No | No | Yes | No | No |
Compressed data | Yes (note 2) | No | Yes | Yes | No |
Data caches | No | N/A | Yes | No | Yes |
Encrypted data | Yes (note 3) | Yes (note 3) | Yes (note 4) | Yes (note 3) | Yes (note 3) |
Foreign key support | No | No | Yes | No | Yes (note 5) |
Full-text search indexes | Yes | No | Yes (note 6) | No | No |
Geospatial data type support | Yes | No | Yes | Yes | Yes |
Geospatial indexing support | Yes | No | Yes (note 7) | No | No |
Hash indexes | No | Yes | No (note 8) | No | Yes |
Index caches | Yes | N/A | Yes | No | Yes |
Locking granularity | Table | Table | Row | Row | Row |
MVCC | No | No | Yes | No | No |
Replication support (note 1) | Yes | Limited (note 9) | Yes | Yes | Yes |
Storage limits | 256TB | RAM | 64TB | None | 384EB |
T-tree indexes | No | No | No | No | Yes |
Transactions | No | No | Yes | No | Yes |
Update statistics for data dictionary | Yes | Yes | Yes | Yes | Yes |
物理文件
物理文件包括:日志文件,數據文件,配置文件,pid 文件,socket 文件等
日志文件
MySQL 5.7 日志文件介紹:https://dev.mysql.com/doc/refman/5.7/en/server-logs.html
Log Type | Information Written to Log |
Error log | Problems encountered starting, running, or stopping mysqld |
General query log | Established client connections and statements received from clients |
Binary log | Statements that change data (also used for replication) |
Relay log | Data changes received from a replication master server |
Slow query log | Queries that took more than long_query_time seconds to execute |
DDL log (metadata log) | Metadata operations performed by DDL statements |
錯誤日志(Error log)
MySQL 錯誤日志記錄 MySQL 運行過程中較為嚴重的警告和錯誤信息,以及 MySQL 每次啟動和關閉的詳細信息。MySQL 錯誤日志默認是開啟的。
可以通過 MySQL 配置文件中的 log-error=/var/log/mysqld.log 配置,修改錯誤日志的配置信息。
可以通過如下 SQL 查看錯誤日志的詳細信息:
show variables like '%log_err%';
通用查詢日志(General query log)
記錄建立的客戶端連接和執行的語句。
可以通過如下 SQL 查看當前的通用日志是否開啟:
SHOW VARIABLES LIKE '%general%';
/*開啟通用日志查詢:*/ set global general_log = on; /*關閉通用日志查詢:*/ set global general_log = off;
二進制日志(Binary log)
MySQL 的二進制日志(binary log)是一個二進制文件,主要用於記錄修改數據或有可能引起數據變更的 MySQL 語句。二進制日志(binary log)中記錄了對 MySQL 數據庫執行更改的所有操作,並且記錄了語句發生時間、執行時長、操作數據等其它額外信息,但是它不記錄 SELECT、SHOW 等那些不修改數據的 SQL 語句。二進制日志(binary log)主要用於數據庫恢復和主從復制,以及審計(audit)操作。
/*刪除所有二進制文件:*/ reset master /*刪除部分二進制文件:*/ purge master logs /*查看是否啟用二進制日志:*/ show variables like '%log_bin%'; /*查看所有的二進制參數*/ show variables like '%binlog%'; /*查看文件的位置*/ show variables like '%datadir%'; /*查看當前服務器所有的二進制日志文件*/ show binary logs; show master logs;
慢查詢日志(Slow query log)
記錄所有執行時間超過 long_query_time 秒的查詢 SQL 或者沒有使用索引的查詢 SQL,默認情況下,MySQL 不開啟慢查詢日志,long_query_time 的默認值為10,即運行時間超過 10s 的語句是慢查詢語句。
/*查看當前慢查詢日志的開啟情況:*/ show variables like '%query%';
- slow_query_log:ON 表示開啟慢查詢日志,OFF 表示關閉慢查詢日志
- slow_query_log_file:記錄慢查詢日志的文件地址(默認為主機名.log)
- long_query_time:指定了慢查詢的閾值,單位是秒,即執行語句的時間若超過這個值則為慢查詢語句
- log_queries_not_using_indexes:ON 表示會記錄所有沒有利用索引來進行查詢的語句,前提是 slow_query_log 的值也是 ON,否則,不會奏效,OFF 表示不會記錄所有沒有利用索引來進行查詢的語句。
配置文件
Linux下 MySQL 的配置文件是 my.cnf,一般會存放在 /etc/my.cnf,/etc/mysql/my.cnf,MySQL 所有的配置信息都存放在該文件中,后面會單獨整理一篇 MySQL 的配置內容介紹。
數據文件
獲取硬盤中數據存儲的地址:
SHOW VARIABLES LIKE 'datadir';
根目錄文件內容:
engine 數據庫文件內容:
db.opt 文件
該文件記錄這個庫的默認使用的字符集和校驗規,文件存放在所屬數據庫的目錄下。
FRM 文件
不論使用什么存儲引擎,每一張表都會有一個以表名命名的 .frm 文件,與表相關的元數據(meta)信息都存放在此文件中,包括表結構的定義信息等,文件存放在所屬數據庫的目錄下。
MYD 文件
MyISAM 存儲引擎專用,存放 MyISAM 表的數據(data)。每一張 MyISAM 表都會有一個 .MYD 文件,文件存放在所屬數據庫的目錄下。
MYI 文件
也是 MyISAM 存儲引擎專用,存放 MyISAM 表的索引相關信息。每一張 MyISAM 表對應一個 .MYI 文件,文件存放在所屬數據庫的目錄下。
IBD 文件和 IBDATA 文件
存放 InnoDB 的數據文件(包括索引)。InnoDB 存儲引擎有兩種表空間方式:獨享表空間和共享表空間。
獨享表空間:使用 .ibd 文件來存放數據,且每一張 InnoDB 表對應一個 .ibd 文件,文件存放在所屬數據庫的目錄下。
共享表空間:使用 .ibdata 文件,所有表共同使用一個(或多個,自行配置).ibdata 文件。
ibdata1 文件
系統表空間(數據文件)undo 段,文件存放在 datadir 目錄下。
ib_logfile0、ib_logfile1 文件
redlog 文件,文件存放在 datadir 目錄下。
pid 文件
pid 文件是 mysqld 應用程序在 Unix/Linux 環境下的一個進程文件,和許多其他 Unix/Linux 服務端程序一樣,它存放着自己的進程 id。
socket 文件
socket 文件也是在 Unix/Linux 環境下才有的,用戶在 Unix/Linux 環境下客戶端連接可以不通過 TCP/IP 網絡而直接使用 Unix Socket 來連接 MySQL。