mysql邏輯架構(gòu)
整體來說,MySql的邏輯架構(gòu)分成三個部分

1)客戶端:主要是建立連接的過程,交互的過程
2)核心服務(wù)
3)存儲引擎
這個可能比較抽象,我們結(jié)合MySql的查詢過程,結(jié)合著進(jìn)行學(xué)習(xí)
MySql查詢過程

這個圖其實(shí)就是在第一個的基礎(chǔ)上,進(jìn)行的更加細(xì)致的劃分,因?yàn)樯厦嬷皇谴笾庐嫵隽诉壿嫾軜?gòu),但是這個就展示了一整個過程。
大致的過程
1)客戶端向服務(wù)端發(fā)起一條請求
2)服務(wù)端先檢查查詢緩存,如果命中緩存,則直接返回結(jié)果,否則交給下一階段
3)服務(wù)器進(jìn)行SQL解析,預(yù)處理,在經(jīng)過查詢優(yōu)化形成對應(yīng)的執(zhí)行計(jì)劃
4)mysql根據(jù)執(zhí)行計(jì)劃,調(diào)用API給存儲引擎,進(jìn)行數(shù)據(jù)的讀取和存儲
5)將結(jié)果返回給客戶端,并緩存查詢結(jié)果
我們先不深入數(shù)據(jù)庫里面,先將mysql的通信協(xié)議搞清楚,也就是執(zhí)行sql語句之前都干了什么。
要了解mysql通信協(xié)議,就要知道m(xù)ysql是通過什么連接的,這個怎么考率的,mysql是應(yīng)用,我們需要實(shí)現(xiàn)的是mysql客戶端與服務(wù)端進(jìn)行通信,這里好比http,所以在客戶端找到服務(wù)端之前,就需要他們所處的物理機(jī)先建立起連接,就如同http建立連接之前,需要tcp先建立連接。
Mysql的主要連接方式包括:Unix套接字,內(nèi)存共享,命名管道,TCP/IP套接字等。
有的同學(xué)可能問了,怎么這么多方式,那我用的哪一種呢,或者是我應(yīng)該用哪一種呢,其實(shí)他們并不是等價的
Unix套接字:
在Linux和Unix環(huán)境下,可以使用Unix套接字進(jìn)行Mysql服務(wù)器的連接;Unix套接字其實(shí)不是一個網(wǎng)絡(luò)協(xié)議,只能在客戶端和Mysql服務(wù)器在同一臺電腦上才可以使用
TCP/IP套接字
任何系統(tǒng)下都可以使用的方式,也是使用的最多的方式,我主要介紹的也是這種方式,其實(shí)熟悉操作系統(tǒng)的朋友應(yīng)該能體會出來,像前兩種,因?yàn)榭蛻舳撕头?wù)端在同一臺主機(jī)上,也就是一臺主機(jī)的兩個應(yīng)用,所以這也就是進(jìn)程間通信的方式,而在不同的主機(jī)上就不一樣了,就需要網(wǎng)絡(luò),需要建立連接。
mysql通信過程
了解了mysql基于的就是tcp的底層協(xié)議,所以必然,需要經(jīng)歷tcp的三次握手,沒錯第一步就是tcp的三次握手。建立連接之后就可以發(fā)送sql命令了嗎,當(dāng)然不能,細(xì)心的同學(xué)會發(fā)現(xiàn),我用客戶端登陸的時候,是需要用戶名,密碼的,這才是真正的mysql客戶端與服務(wù)端的交互過程,之前還沒有到應(yīng)用層,下面就說一下,交互過程
mysql客戶端與服務(wù)端的交互過程
主要分為兩部分:握手認(rèn)證階段,命令執(zhí)行階段
注意,這個握手和上面過的握手不一樣的。
1.1握手認(rèn)證階段
握手認(rèn)證階段為客戶端與服務(wù)器建立連接后進(jìn)行,交互過程如下
服務(wù)器 -> 客戶端:握手初始化消息
客戶端 -> 服務(wù)器:登陸認(rèn)證消息
服務(wù)器 -> 客戶端:認(rèn)證結(jié)果消息
1.2命令執(zhí)行階段
客戶端認(rèn)證成功后,會進(jìn)入命令執(zhí)行階段,交互過程如下:
客戶端 -> 服務(wù)器:執(zhí)行命令消息
服務(wù)器 -> 客戶端:命令執(zhí)行結(jié)果

為什么還要進(jìn)行三次握手認(rèn)證
因?yàn)閠cp三次握手,只是將客戶端與服務(wù)端建立起了連接,然后通過端口知道我要訪問的是mysql這個服務(wù),但是mysql它不同于http,只要你知道url就能得到一個響應(yīng),mysql必須登陸后你才能進(jìn)行操作。所以這個過程最重要的就是驗(yàn)證客戶端的登陸權(quán)限。
為什么是服務(wù)端主動給客戶端發(fā)送認(rèn)證呢?
mysql報文
主要分成三個部分:登錄認(rèn)證報文,客戶端請求報文以及服務(wù)器端返回報,基于mysql5.1.73(mysql4.1以后的版本)
登陸認(rèn)證報文
1)握手初始化報文(服務(wù)端->客戶端)

- 協(xié)議版本號:服務(wù)端所使用的mysql協(xié)議的版本號
- 服務(wù)器線程ID:服務(wù)端為此客戶端所創(chuàng)建的線程的ID
- 挑戰(zhàn)隨機(jī)數(shù):MySQL數(shù)據(jù)庫用戶認(rèn)證采用的是挑戰(zhàn)/應(yīng)答的方式,服務(wù)器生成該挑戰(zhàn)數(shù)并發(fā)送給客戶端,由客戶端進(jìn)行處理并返回相應(yīng)結(jié)果,然后服務(wù)器檢查是否與預(yù)期的結(jié)果相同,從而完成用戶認(rèn)證的過程。
- 服務(wù)器權(quán)能標(biāo)志:用于與客戶端協(xié)商通訊方式
登陸認(rèn)證報文(客戶端 -> 服務(wù)器)


- 客戶端權(quán)能標(biāo)志: 客戶端收到服務(wù)器發(fā)來的初始化報文后,會對服務(wù)器發(fā)送的權(quán)能標(biāo)志進(jìn)行修改,保留自身所支持的功能,然后將權(quán)能標(biāo)返回給服務(wù)器,從而保證服務(wù)器與客戶端通訊的兼容性。
- 消息長度: 客戶端發(fā)送請求時所支持的最大消息長度值
- 字符編碼: 表示通訊過程中使用的字符編碼,與服務(wù)器在認(rèn)證報文中發(fā)送的相同
- 用戶名: 客戶端登陸的用戶名
- 挑戰(zhàn)認(rèn)證數(shù)據(jù):客戶端用戶密碼使用服務(wù)器發(fā)送的挑戰(zhàn)隨機(jī)數(shù)進(jìn)行加密后,生成挑戰(zhàn)認(rèn)證數(shù)據(jù),返回給服務(wù)器用于服務(wù)端的認(rèn)證
服務(wù)端認(rèn)證結(jié)果報文(服務(wù)端->客戶端)
服務(wù)端主要驗(yàn)證,用戶名,密碼是否正確存在,如果都是正確的,就返回ok報文,錯誤的話就是ERROR報文
好了,我相信大家應(yīng)該都有一定的了解了,那么現(xiàn)在再想一下那個問題(為什么是服務(wù)端主動給客戶端發(fā)送認(rèn)證呢?)是不是覺得是非常有道理的,之所以服務(wù)端先發(fā)送一個握手過去,就是提前通知一下客戶端,你要遵循的一些協(xié)議.