徹底弄懂mysql(一) mysql的通訊協議

2021-09-18 01:54:33 字數 3607 閱讀 6374

我準備從mysql的實現出發,將mysql好好理解一下,從他的邏輯結構一層一層出發,感受一下,所以再學第一層之前,要先對mysql整體的邏輯結構有乙個初步認識

整體來說,mysql的邏輯架構分成三個部分,這個之前我以為提到過

1)客戶端:主要是建立連線的過程,互動的過程

2)核心服務

3)儲存引擎

這個可能比較抽象,我們結合mysql的查詢過程,結合著進行學習

這個圖其實就是在第乙個的基礎上,進行的更加細緻的劃分,因為上面只是大致畫出了邏輯架構,但是這個就展示了一整個過程。

1)客戶端向服務端發起一條請求

2)服務端先檢查查詢快取,如果命中快取,則直接返回結果,否則交給下一階段

3)伺服器進行sql解析,預處理,在經過查詢優化形成對應的執行計畫

4)mysql根據執行計畫,呼叫api給儲存引擎,進行資料的讀取和儲存

5)將結果返回給客戶端,並快取查詢結果

要了解mysql通訊協議,就要知道mysql是通過什麼連線的,這個怎麼考率的,mysql是應用,我們需要實現的是mysql客戶端與服務端進行通訊,這裡好比http,所以在客戶端找到服務端之前,就需要他們所處的物理機先建立起連線,就如同http建立連線之前,需要tcp先建立連線。

mysql的主要連線方式包括:unix套接字,記憶體共享,命名管道,tcp/ip套接字等。

有的同學可能問了,怎麼這麼多方式,那我用的哪一種呢,或者是我應該用哪一種呢,其實他們並不是等價的

unix套接字:

在linux和unix環境下,可以使用unix套接字進行mysql伺服器的連線;unix套接字其實不是乙個網路協議,只能在客戶端和mysql伺服器在同一臺電腦上才可以使用

命名管道和記憶體共享

在window系統中客戶端和mysql伺服器在同一臺電腦上,可以使用命名管道和共享記憶體的方式,

命名管道開啟:–shared-memory=on/off;

共享記憶體開啟:–enable-named-pipe=on/off;

tcp/ip套接字

任何系統下都可以使用的方式,也是使用的最多的方式,我主要介紹的也是這種方式

其實熟悉作業系統的朋友應該能體會出來,像前兩種,因為客戶端和服務端在同一臺主機上,也就是一台主機的兩個應用,所以這也就是程序間通訊的方式,而在不同的主機上就不一樣了,就需要網路,tcp/ip建立了。

了解了mysql基於的就是tcp的底層協議,所以必然,需要經歷tcp的三次握手,沒錯第一步就是tcp的三次握手(因為這裡不是重點,就不詳細說明,不太清楚的同學,可以檢視我network的相關部落格),建立連線之後就可以傳送sql命令了嗎,當然不能,細心的同學會發現,我用客戶端登陸的時候,是需要使用者名稱,密碼的,這才是真正的mysql客戶端與服務端的互動過程,之前還沒有到應用層,下面就說一下,互動過程

主要分為兩部分:握手認證階段,命令執行階段

注意哦,這個握手和上面過的握手不一樣哦

握手認證階段為客戶端與伺服器建立連線後進行,互動過程如下:

伺服器 -> 客戶端:握手初始化訊息

客戶端 -> 伺服器:登陸認證訊息

伺服器 -> 客戶端:認證結果訊息

客戶端認證成功後,會進入命令執行階段,互動過程如下:

客戶端 -> 伺服器:執行命令訊息

伺服器 -> 客戶端:命令執行結果

不知道大家看了有沒有產生一些問題,那我就我的一些問題說一下

為什麼還要進行三次握手認證

因為tcp三次握手,只是將客戶端與服務端建立起了連線,然後通過埠知道我要訪問的是mysql這個服務,但是mysql它不同於http,只要你知道url就能得到乙個響應,mysql必須登陸後你才能進行操作。所以這個過程最重要的就是驗證客戶端的登陸許可權。

為什麼是服務端主動給客戶端傳送認證呢?

http不是說只有客戶端主動與服務端進行請求,服務端不是不能在沒有請求的情況下主動進行響應嗎?

首先,大家也不要陷入誤區,在進行認證的這個互動中,實際上客戶端與服務端還沒有進行任何業務上的往來,只是進行乙個認證,所以與上面說的http的不同,如果細心的話你會發現,認證成功後,在命令執行階段,mysql這種通訊方式是與http非常類似的,在沒有請求的情況下,服務端的mysql也不會主動給你傳送任何資料,所以這裡不要混淆。

再說為什麼服務端先傳送,那肯定是因為他有不得不傳送的道理,所以我們就需要理解一下,他傳送的是什麼東西。

主要分成三個部分:登入認證報文,客戶端請求報文以及伺服器端返回報,基於mysql5.1.73(mysql4.1以後的版本)

1)握手初始化報文(服務端->客戶端)

協議版本號:服務端所使用的mysql協議的版本號

伺服器執行緒id:服務端為此客戶端所建立的執行緒的id

挑戰隨機數:mysql資料庫使用者認證採用的是挑戰/應答的方式,伺服器生成該挑戰數並傳送給客戶端,由客戶端進行處理並返回相應結果,然後伺服器檢查是否與預期的結果相同,從而完成使用者認證的過程。

**伺服器權能標誌:**用於與客戶端協商通訊方式

這個我稍微解釋下,他這個只要傳送的就是,我服務端能接受的通訊方式是什麼樣的,我們下面詳細說一下

登陸認證報文(客戶端 -> 伺服器)

客戶端權能標誌客戶端收到伺服器發來的初始化報文後,會對伺服器傳送的權能標誌進行修改,保留自身所支援的功能,然後將權能標返回給伺服器,從而保證伺服器與客戶端通訊的相容性。

訊息長度客戶端傳送請求時所支援的最大訊息長度值

字元編碼表示通訊過程中使用的字元編碼,與伺服器在認證報文中傳送的相同

使用者名稱客戶端登陸的使用者名稱

挑戰認證資料:客戶端使用者密碼使用伺服器傳送的挑戰隨機數進行加密後,生成挑戰認證資料,返回給伺服器用於服務端的認證

服務端認證結果報文(服務端->客戶端)

這個就比較好理解了,服務端主要驗證,使用者名稱,密碼是否正確存在,如果都是正確的,就返回ok報文,錯誤的話就是error報文

好了,我相信大家應該都有一定的了解了,那麼現在再想一下那個問題是不是覺得是非常有道理的,之所以服務端先傳送乙個握手過去,就是提前通知一下客戶端,你要遵循的一些協議小明接收到這個訊息之後,到了那個時間他就會請求那個**,並將自己的資訊告訴他

這時候公司驗證你的資訊,驗證成功後,你就可以開始筆試了

大家可以模擬這理解一下,就能體會出,這是非常有必要的。

這一章先講這麼多,下一張我們講一下,挑戰隨機數和全能標誌位的原理,有興趣的同學可以關注一下,有問題也可以隨時交流。

徹底弄懂session,cookie,token

我在寫之前看了很多篇session,cookie的文章,有的人說先有了cookie,後有了session。也有人說先有session,後有cookie。感覺都沒有講的很清楚,泛泛而談。希望本篇文章對大家有所幫助 注 本文需要讀者有cookie,session,token的相關基礎知識。什麼是無狀態呢...

徹底弄懂 Unicode 編碼

原文 今天,在學習 node.js 中的 buffer 物件時,注意到它的 alloc 和 from 方法會預設用utf 8編碼,在陣列中每位對應 1 位元組的十六進製制數。想到了之間學習 es6 時關於字串的 unicode 表示法,突然就很想知道 utf 16 是如何進行編碼的,我嘗試將一些漢字...

徹底弄懂Redis set篇

redis中有兩種集合,一種是無序集合,一種是有序集合,他們之間的相同點就是不重複,不同點就是是否有序,我們分別介紹一下。因為set只要保證加入的元素不重複就好,所以他的底層實現也比較簡單,就是乙個value為空的雜湊表,key就是用來儲存加入的元素值的,我們今天重點介紹的就是sort set 有序...