如果能夠清楚知道的架構(gòu)圖以及各個(gè)組件之間的關(guān)聯(lián)母截,會(huì)有助于深入理解mysql济蝉,如下是其的架構(gòu)圖
圖中可以看出mysql分為service層和存儲(chǔ)引擎層:
service層包含了mysql大多數(shù)核心功能旦部,除了圖中標(biāo)注的連接器,查詢緩存,分析器罐旗,優(yōu)化器,執(zhí)行器唯蝶,還有所有的內(nèi)置函數(shù)(日期九秀,時(shí)間,數(shù)學(xué)和加密函數(shù))粘我,所有跨存儲(chǔ)引擎的功能都在這一層實(shí)現(xiàn):存儲(chǔ)過(guò)程鼓蜒、觸發(fā)器、視圖等征字。
存儲(chǔ)引擎層負(fù)責(zé)mysql中數(shù)據(jù)的存儲(chǔ)和提取都弹。和Linux下的各種文件系統(tǒng)一樣,每個(gè)存儲(chǔ)引擎都有自己的優(yōu)勢(shì)和劣勢(shì)柔纵,各種存儲(chǔ)引擎通過(guò)提供API和service層對(duì)接缔杉,通過(guò)API屏蔽各種存儲(chǔ)引擎之間的差異。常見(jiàn)的存儲(chǔ)引擎有InnoDB搁料、MyISAM或详、Memory,現(xiàn)在最常用的是InnoDB郭计,也是從mysql5.5版本開始成為默認(rèn)的存儲(chǔ)引擎霸琴,在5.5之前默認(rèn)的是MyISAM
1. 連接器
連接器是mysql service層的第一個(gè)模塊,也是處理客戶端請(qǐng)求的模塊昭伸。
客戶端和服務(wù)端的連接是使用經(jīng)典的tcp協(xié)議梧乘,經(jīng)過(guò)tcp握手之后,連接器開始進(jìn)行身份驗(yàn)證
登錄命令
mysql -h$ip -P$port -u$user -p
- 如果賬號(hào)或者密碼錯(cuò)誤,會(huì)提示
Access denied for user
- 如果正確則認(rèn)證通過(guò)选调,之后會(huì)查詢當(dāng)前用戶的權(quán)限夹供,之后用戶的操作都是在這個(gè)權(quán)限范圍中,如果在連接期間修改權(quán)限也是無(wú)效的仁堪,需要重新連接才會(huì)生效哮洽。
如下命令也是可以的,但是這種命令會(huì)把密碼暴漏出來(lái)弦聂,建議還是使用如上圖方式鸟辅,采用交互交互輸入密碼更安全
mysql -h$ip -P$port -u$user -p$password
2. 查詢緩存
了解即可,mysql8.0版本就去除緩存模塊了
客戶端發(fā)送一個(gè)sql查詢請(qǐng)求后莺葫,會(huì)先去緩存中查看是否存在匪凉。如果之前這條sql已經(jīng)執(zhí)行過(guò),而且結(jié)果緩存起來(lái)捺檬,那么這次查詢就會(huì)直接從緩存中獲取結(jié)果返回再层,不會(huì)在走分析器,優(yōu)化器堡纬,執(zhí)行器树绩。如果緩存中沒(méi)有命中,才會(huì)繼續(xù)走后面的模塊隐轩。
緩存以key-value的形式存儲(chǔ)饺饭,存放在一個(gè)引用表中海诲,key是通過(guò)一個(gè)哈希值的引用躬络,這個(gè)哈希值包括查詢本身(sql),當(dāng)前要查詢的數(shù)據(jù)庫(kù),客戶端協(xié)議的版本等一些其他會(huì)影響返回結(jié)果的的信息坯沪;查詢結(jié)果作為value(任何字符上的變化悴灵,例如空格扛芽,注釋都會(huì)導(dǎo)致緩存不命中)。
如果表被更改积瞒,所有的緩存都將失效川尖,表的更改是指數(shù)據(jù)的改變和表結(jié)構(gòu)的改變,包括INSERT茫孔、UPDATE叮喳、 DELETE、TRUNCATE缰贝、ALTER TABLE馍悟、DROP TABLE或DROP DATABASE等。
對(duì)于經(jīng)常變更的數(shù)據(jù)庫(kù)來(lái)說(shuō)緩存命中率就很低了 剩晴,查詢緩存往往弊大于利锣咒,所以不建議使用mysql的緩存侵状,而對(duì)于長(zhǎng)時(shí)間不變化的表可以使用redis緩存。mysql在8.0就完全去掉查詢緩存模塊了毅整。
3. 分析器
我們根據(jù)mysql語(yǔ)法寫出來(lái)一個(gè)sql之后交給服務(wù)層趣兄,分析器對(duì)sql語(yǔ)句進(jìn)行詞法分析和語(yǔ)法分析。
Mysql通過(guò)識(shí)別字符串中列名悼嫉、表名诽俯、where、select/update/insert 等mysql關(guān)鍵字承粤,在根據(jù)語(yǔ)法規(guī)則判斷sql是否滿足語(yǔ)法,最終會(huì)生成一個(gè)抽象語(yǔ)法樹(AST)闯团。
mysql分析器使用mysql語(yǔ)法規(guī)則驗(yàn)證和解析查詢辛臊,例如驗(yàn)證是否使用錯(cuò)誤的關(guān)鍵字或者使用關(guān)鍵字的順序是否正確,再或者會(huì)驗(yàn)證引號(hào)是否能前后正確匹配房交。
如果關(guān)鍵字有誤會(huì)提示You have an error in your SQL syntax
的信息彻舰,具體錯(cuò)誤需要關(guān)注use near
后的內(nèi)容
mysql> elect * from iam_user where id = 0;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'elect * from iam_user where id = 0' at line 1
4. 優(yōu)化器
經(jīng)過(guò)分析器生成的語(yǔ)法樹被認(rèn)為是合法的,并由優(yōu)化器轉(zhuǎn)化成執(zhí)行計(jì)劃
mysql判斷出了這條sql需要做什么之后候味,對(duì)其進(jìn)行各種優(yōu)化刃唤,包括重寫查詢,決定表的讀取順序白群,以及選擇合適的索引等尚胞。
mysql使用基于成本的優(yōu)化的優(yōu)化器,嘗試預(yù)測(cè)一個(gè)查詢使用某種執(zhí)行計(jì)劃時(shí)的成本帜慢,選擇最小的那一個(gè)笼裳。
例如表中有多個(gè)索引的時(shí)候決定使用哪一個(gè);使用聯(lián)合索引的時(shí)候,會(huì)根據(jù)所以調(diào)整where條件的順序粱玲;
如果想知道優(yōu)化器是怎么進(jìn)行優(yōu)化決策的躬柬,可以通過(guò)explain獲取優(yōu)化的信息,explain具體的使用和解釋后面章節(jié)會(huì)說(shuō)明的抽减。
5. 執(zhí)行器
調(diào)用存儲(chǔ)引擎的API操作數(shù)據(jù)
優(yōu)化器完成sql的優(yōu)化后允青,提供一個(gè)執(zhí)行計(jì)劃給執(zhí)行器,執(zhí)行器開始執(zhí)行這個(gè)執(zhí)行計(jì)劃來(lái)操作數(shù)據(jù)卵沉。
執(zhí)行查詢階段:mysql只是簡(jiǎn)單的根據(jù)執(zhí)行計(jì)劃給出的指令逐步執(zhí)行颠锉,通過(guò)調(diào)用存儲(chǔ)引擎實(shí)現(xiàn)的接口來(lái)完成的。
總結(jié):用一個(gè)sql的執(zhí)行過(guò)程來(lái)總結(jié)下
客戶端發(fā)送一條查詢給服務(wù)器史汗。
服務(wù)器先檢查查詢緩存木柬,如果命中緩存則直接返回緩存中的結(jié)果。否則進(jìn)入下一階段淹办。
服務(wù)器進(jìn)行sql解析眉枕,預(yù)處理,再由優(yōu)化器生成執(zhí)行計(jì)劃。
mysql根據(jù)執(zhí)行計(jì)劃速挑,調(diào)用存儲(chǔ)引擎的API來(lái)執(zhí)行查詢谤牡。
將結(jié)果返回給客戶端。