前言
瞭解Mysql的架構體系,對mysql的學習以及性能優化有很大的幫助。比如很多查詢優化工作實際上就是遵循服務層的一些原則讓mysql優化器能夠按照預想的合理方式運行。mysql整體架構分爲4層,如下圖。
自頂向下分別爲:網絡連接層、服務層、存儲引擎層、系統文件層
一、網絡連接層
1、功能
主要負責連接管理、授權認證、安全等。
當 MySQL 啓動(MySQL 服務器就是一個進程),等待客戶端連接,每一個客戶端連接請求, 服務器都會新建一個線程處理(如果是線程池的話,則是分配一個空的線程),每個線程獨 立,擁有各自的內存處理空間。
// 查看mysql允許的最大連接數
show VARIABLES like '%max_connections%'
連接到服務器,服務器需要對其進行驗證,也就是用戶名、IP、密碼驗證,一旦連接成功, 還要驗證是否具有執行某個特定查詢的權限(例如,是否允許客戶端對某個數據庫某個表的 某個操作)
二、服務層(核心層)
主要功能:sql語句的解析、優化、查詢緩存,MySQL 內置函數的實現,跨存儲引擎功能(所謂跨存儲引擎就是說每個引擎都需提供的功能(引擎需對外提供接口)),例如: 存儲過程、觸發器、視圖等。
2⃣️查詢緩存
如果是查詢語句(select 語句),首先會查詢緩存是否已有相應結果,有則返回結果,無則 進行下一步(如果不是查詢語句,同樣調到下一步)
// 查看緩存是否開啓-- 默認不開啓
show variables like '%query_cache_type%'
// 查看緩存大小--默認值 1M
show variables like '%query_cache_size%'
// 會報錯,query_cache_type 只能配置在 my.cnf 文件中
SET GLOBAL query_cache_type = 1
在生產環境建議不開啓,除非經常有 sql 完全一模一樣的查詢。 QC 嚴格要求 2 次 SQL 請求要完全一樣,包括 SQL 語句,連接的數據庫、協議版本、字符 集等因素都會影響
3⃣️解析器與預處理器
MySQL會解析查詢,並創建了一個內部數據結構(解析樹)。這個過程解析器主要通過語法
規則來驗證和解析。比如SQL中是否使用了錯誤的關鍵字或者關鍵字的順序是否正確等等。預處理會根據MySQL的規則進一步檢查解析樹是否合法。比如要查詢的數據表和數據列是否存在等
。
4⃣️查詢優化器:
優化器將其轉化成查詢計劃。多數情況下,一條查詢可以有很多種執行方式,最後都返回相應的結果。優化器的作用就是找到這其中最好的執行計劃。優化器並不關心使用的什麼存儲引擎,但是存儲引擎對優化查詢是有影響的。優化器要求存儲引擎提供容量或某個具體操作的開銷信息來評估執行時間。
5⃣️查詢引擎
在完成解析和優化階段以後,MySQL會生成對應的執行計劃,查詢執行引擎根據執行計劃給出的指令調用存儲引擎的接口得出結果。
三、存儲引擎層
1、作用
負責MySQL中數據的存儲與提取。 服務器中的查詢執行引擎通過API與存儲引擎進行通信,通過接口屏蔽了不同存儲引擎之間的差異。
存儲引擎是針對於表的而不是針對庫的(一個庫中不同表可以使用不同的存儲引擎),服務器通過API與存儲引擎進行通信,用來屏蔽不同存儲引擎之間的差異。
#看你的 mysql 現在已提供什麼存儲引擎:
mysql> show engines;
#看你的 mysql 當前默認的存儲引擎:
mysql> show variables like '%storage_engine%';
2、MyISAM
2.1特點
不支持事務、併發加表鎖、支持全文搜索。
支持壓縮
myisampack -b -f /usr/local/mysql/data/mall/testmysam.MYI
# 壓縮後再往表裏面新增數據就新增不了
insert into testmysam VALUES(1),(2),(3
2.2適用場景
- 非事務型應用(數據倉庫,報表,日誌數據)
- 只讀類應用
- 空間類應用(空間函數,座標)
3、Innodb
3.1特點
- Innodb 是一種事務性存儲引擎
- 完全支持事務得ACID特性
- Redo Log 和 Undo Log
- Innodb支持行級鎖(併發程度更高)
3.2對比
4、CSV
4.1特點
- 以csv格式進行數據存儲
- 所有列都不能爲null的
- 不支持索引(不適合大表,不適合在線處理)
- 可以對數據文件直接編輯(保存文本文件內容)
# 建表
create table mycsv(id int not null,
c1 VARCHAR(10) not null,
c2 char(10) not null)
engine=csv;
# 插入數據
insert into mycsv values(1,'aaa','bbb'),(2,'cccc','dddd');
# 打開csv數據,修改文本數據
vi /usr/local/mysql/data/mall/mycsv.CSV
# 刷新修改後的數據
flush TABLES;
# 查找數據,發現數據和在文本中修改的數據相同
select * from mycsv
// 創建索引報錯,csv存儲引擎不支持索引
create index idx_id on mycsv(id)
5、Archive
以 zlib 對錶數據進行壓縮,磁盤 I/O 更少 數據存儲在 ARZ 爲後綴的文件中
5.1特點
- 只支持 insert 和 select 操作
- 只允許在自增 ID 列上加索引
5.2適用場景
日誌系統
6、Memory
6.1特點
- HEAP 存儲引擎,所以數據保存在內存中
- 支持HASH索引和BTree索引
- 所有字段都是固定長度 varchar(10) = char(10)
- 不支持Blog和Text等大字段
- Memory存儲引擎使用表級鎖
- 最大大小由max_heap_table_size參數決定
6.2與臨時表的區別
6.3適用場景
- hash索引用於查找或者是映射表(郵編和地區的對應表)
- 用於保存數據分析中產生的中間表
- 用於緩存週期性聚合數據的結果表
7、Ferderated
7.1、特點:
- 提供了訪問遠程MySQL服務器上表的方法
- 本地不存儲數據,數據全部放到遠程服務器上
- 本地需要保存表結構和遠程服務器的連接信息
7.2、使用場景
偶爾的統計分析及手工查詢(某些遊戲行業)
# 建表
create database local;
# 建庫
create database remote;
# 建表
create table remote_fed
(id int auto_increment not null,
c1 varchar(10) not null default '',
c2 char(10) not null default '',
primary key(id)) engine = INNODB
# 插入數據
INSERT into remote_fed(c1,c2) values('aaa','bbb'),('ccc','ddd'),('eee','fff');
# 建表
CREATE TABLE `local_fed` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c1` varchar(10) NOT NULL DEFAULT '',
`c2` char(10) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)) ENGINE=federated CONNECTION='mysql://root:root1234%@127.0.0.1:3306/remote/remote_fed'
# 訪問本地庫即可訪問遠程innodb的數據庫
select * from local_fed
delete from local_fed where id = 2 select * from remote.remote_fed
四、系統文件層-物理存儲結構
1、數據庫的數據庫(DataDir)
mysql 安裝的時候都要指定 datadir,其查看方式爲,其規定所有建立的數據庫存放位置
show VARIABLES like 'datadir'
2、數據庫
創建了一個數據庫後,會在上面的 datadir 目錄新建一個子文件夾
3、表文件
用戶建立的表都會在上面的目錄中,它和具體的存儲引擎相關,但有個共同的就是都有個 frm 文件,它存放的是表的數據格式
查看錶的結構
mysqlfrm --diagnostic /usr/local/mysql/data/mall/account.frm
3.1MyISAM表結構
- frm文件:與表相關的元數據信息都存放在frm文件,包括表結構的定義信息等。
- MYD文件:MyISAM存儲引擎專用,用於存儲MyISAM表的數據
- MYI文件:MyISAM存儲引擎專用,用於存儲MyISAM表的索引相關信息
3.2InnoDb表結構
- frm文件:與表相關的元數據信息都存放在frm文件,包括表結構的定義信息等
- ibd文件:存放innodb表的數據文件。
注:除了.ibd文件InnoDB還有一種文件的存儲格式爲.ibdata文件,那麼他們之間有什麼區別呢?
.ibd存儲的是獨享表空間數據,並且每個表一個ibd文件。
.ibdata文件是共享表空間存儲方式,所有的表共同使用一個ibdata文件,即所有的數據文件都存在一個文件中。
配置
決定使用哪種表的存儲方式可以通過mysql的配置文件中 innodb_file_per_table選項來指定
InnoDB默認使用的是獨享表的存儲方式,這種方式的好處是當數據庫產生大量文件碎片的時,整理磁盤碎片對線上運行環境的影響較小