MySql協(xié)議
簡(jiǎn)介
mysql是我們大家都在用的數(shù)據(jù)庫(kù),我們對(duì)mysql的認(rèn)知可能還停留在DDL,索引以及一些優(yōu)化層面,那么我們知道我們常用的navicat以及開(kāi)發(fā)人員常用的java jdbc, go-jdbc以及c#的Jdbc是怎么跟mysql數(shù)據(jù)庫(kù)進(jìn)行連接并交互的嗎?這里不得不說(shuō)mysql的協(xié)議,我們大家都知道協(xié)議就是一個(gè)約定俗成的合約,任何要跟我發(fā)生聯(lián)系或者交易的人都要遵守我的約定,這樣才能統(tǒng)一進(jìn)行交互,而不用搞得本身很復(fù)雜。下面我將帶大家來(lái)認(rèn)識(shí)一下mysql的協(xié)議。
交互過(guò)程
mysql客戶端與mysql服務(wù)器的交互主要分為:握手認(rèn)證階段以及命令執(zhí)行階段
握手認(rèn)證階段
mysql客戶端在與mysql建立連接時(shí),會(huì)先進(jìn)行tcp三次握手->mysql握手認(rèn)證->mysql命令執(zhí)行->tcp四次揮手這幾個(gè)階段,握手認(rèn)證階段在tcp三次握手之后,由mysql服務(wù)器首先響應(yīng)的第一次握手請(qǐng)求。
[圖片上傳失敗...(image-58f6ef-1612622547424)]
握手信息初始化
握手信息初始化主要是將mysql的一些版本信息,支持的一些功能在這一階段返回給客戶端,我們可以來(lái)看看發(fā)送了哪些信息。
1 [0a] protocol version
string[NUL] server version
4 connection id
string[8] auth-plugin-data-part-1
1 [00] filler
2 capability flags (lower 2 bytes)
if more data in the packet:
1 character set
2 status flags
2 capability flags (upper 2 bytes)
if capabilities & CLIENT_PLUGIN_AUTH {
1 ength of auth-plugin-data
} else {
1 [00]
}
string[10] reserved (all [00])
if capabilities & CLIENT_SECURE_CONNECTION {
string[$len] auth-plugin-data-part-2 ($len=MAX(13, length of auth-plugin-data - 8))
if capabilities & CLIENT_PLUGIN_AUTH {
string[NUL] auth-plugin name
}
- 1byte版本號(hào)
- nbyte服務(wù)器版本信息
- 4byte服務(wù)器線程id
- 8byte挑戰(zhàn)隨機(jī)數(shù)
- 1byte填充值
- 2byte服務(wù)器權(quán)能標(biāo)志
- 1byte字符編碼
- 2byte服務(wù)器狀態(tài)
- 2byte服務(wù)器權(quán)能標(biāo)志(高16位)
- 1byte挑戰(zhàn)長(zhǎng)度(未使用)
- 10byte填充值
- nbyte挑戰(zhàn)隨機(jī)數(shù)(第二部分,至少12字節(jié))
這里握手初始化中比較需要注意的是這個(gè)權(quán)能標(biāo)志,具體可看官網(wǎng),目前很多數(shù)據(jù)庫(kù)會(huì)利用這里的字段來(lái)開(kāi)發(fā)出自己所支持的能力。
客戶端登錄認(rèn)證
客戶端收到服務(wù)器的初始化信息包,拿到之后會(huì)根據(jù)其中的一些狀態(tài)做一下校驗(yàn),然后再發(fā)送自己的登錄認(rèn)證包給服務(wù)器請(qǐng)求授權(quán)

同樣,客戶端也會(huì)帶上權(quán)能標(biāo)志

服務(wù)端返回認(rèn)證成功
如果客戶端請(qǐng)求用戶密碼以及支持權(quán)能標(biāo)志全部符合要求,則會(huì)認(rèn)證通過(guò),服務(wù)器會(huì)返回ok包

至此,整個(gè)交互認(rèn)證已經(jīng)全部執(zhí)行完畢,接下來(lái)就是真正的執(zhí)行命令階段了
命令執(zhí)行階段
mysql客戶端在完成建立連接后會(huì)執(zhí)行命令,命令執(zhí)行階段就是mysql將sql語(yǔ)句已經(jīng)參數(shù)進(jìn)行綁定傳入到mysql服務(wù)器進(jìn)行執(zhí)行并拿到結(jié)果,在這過(guò)程中,mysql服務(wù)器也是支持服務(wù)器預(yù)編譯的,所以我們可以在連接的url里進(jìn)行配置,比如mysql的jdbc就是支持服務(wù)器預(yù)編譯,然后客戶端也進(jìn)行相應(yīng)的支持的。在mysql的jdbc源碼里,最需要處理的就是各個(gè)參數(shù)類型的處理,以及兼容。每個(gè)類型都有不同的處理方式以及字節(jié)長(zhǎng)度。這個(gè)可以看mysql的具體協(xié)議。