深度解析mysql登入原理

2021-07-22 03:35:36 字數 3918 閱讀 3632

使用mysql資料庫的第一步必然是建立連線登入,然後在上面執行sql命令。無論是通過mysql的客戶端,還是通過c-api,jdbc標準介面連線資料庫,這個過程一定少不了。今天我們聊一聊mysql登陸具體過程,裡面會涉及client與server的互動,並通過tcpdump抓包給大家展現這一過程。

tcp握手協議

遠端連線資料庫,mysql採用tcp協議通訊,第一步是建立連線,即tcp的3次握手。mysql server端有乙個監聽執行緒等待client請求,

client發起請求後,首先發乙個sync包到服務端,服務端發乙個ack包作為對客戶端sync包的響應,同時發乙個sync包到客戶端,

最後客戶端再發乙個ack包作為對服務端的響應。通過3次握手,tcp連線才算真正建立起來,這個時候mysql服務端會分配乙個連線供

客戶端使用。記住,tcp的3次握手都是由tcp的協議棧完成,應用程式並無感知。但是,到目前為止,整個mysql連線過程還只完成了

第一步--建立tcp連線。

下面附上tcp建立連線和斷開連線的原理圖。

mysql握手協議

tcp連線建立成功後,mysql客戶端與mysql服務端開始進行通訊,進行mysql認證過程。(1)服務端首先會發乙個握手包到客戶端,(2)然後客戶端向服務端傳送認證資訊(使用者名稱,密碼等),(3)服務端收到認證包後,會檢查使用者名稱與密碼是否合法,並傳送包告知客戶端認證資訊。如果合法,則登陸成功,否則,登陸失敗。連線報錯。有時候,我們通過show processlist看到user處於unauthenticated user ,這說明此時連線過程正處於第1步和第2步之間,服務端等待客戶端發認證資訊的過程中。

15922528       unauthenticated user

10.xx.2.74:53216

null connect null reading from net null

15923418 unauthenticated user connecting host null connect null login null

tcpdump抓包驗證

下面我們通過tcpdump抓網路包來驗證我們的原理。由於測試在生產環境中進行,為了避免生產網段的ip洩露,對ip作了替換,但不影響分析過程。具體而言,10.aa.zz.142.10556代表客戶端,10.bb.yy.104.3306代表伺服器端,3306是伺服器的監聽埠號。

(1).在客戶端上開啟tcpdump命令,監聽與10.bb.yy.104.3306的通訊網路包,命令如下:

tcpdump -s -nn -tttt -i eth0 host 10.bb.yy.104 and port 3306 and tcp -c 100

-s 將tcp的序列號以絕對值形式輸出,而不是相對值。

-nn 不進行埠名稱的轉換。

-tttt 在每一行中輸出由date處理的預設格式的時間戳。

-i eth0 指定監聽的網路介面

host

10.bb.yy.104

and port 3306 設定監聽10.bb.yy.104

:3306的網路包

-c 100 表示監聽100包就結束。

(2).在客戶端上,利用mysql命令遠端連線服務端10.bb.yy.104,

mysql –h10.bb.yy.104 –p3306 –u*** –p***
登陸成功後,然後直接執行exit,退出

(3)分析tcpdump抓取的網路包,重點分析建立tcp連線,mysql認證和tcp斷開連線的過程。如下圖,圖中第1部分是tcp連線建立的過程,第2部分是mysql認證的過程,第3部分是登陸成功後,傳送基本元資料資訊的過程,第4部分是斷開連線的過程。通過圖中的標示,我們可以清晰的看到tcp建立連線的3次握手,mysql認證以及tcp斷開連線的4次揮手過程。

建立連線

這個過程主要體現在第一部分,客戶端10.aa.zz.142.10556,首先發乙個編號為1491894492的syn包,服務端收到後,傳送了1491894492+1的ack包,並傳送了乙個2727774925的syn包,最後客戶端再傳送乙個2727774925+1的包進行應答。

mysql認證

這個過程主要體現在第二部分,服務端10.bb.yy.104:3306首先發乙個認證包給客戶端,然後客戶端再傳送包含使用者密碼的認證包給伺服器,驗證成功後,服務端最後給客戶端乙個應答,那麼整個認證過程就結束了,至於第3部分是服務端與客戶端相互傳送的一些元資料資訊,比如版本資訊之類的。

斷開連線

這個過程主要體現在第四部分,客戶端發起exit命令時,開始觸發這個動作。客戶端首先發乙個編號為1491894724的fin包,然後伺服器傳送乙個1491894724+1的ack包作為應答,並傳送乙個編號為2727775120的fin包,最後客戶端傳送2727775120+1作為應答,整個過程結束。

資料報標記解析

s=syn   發起連線標誌,一般用於建立tcp連線

p=push 傳送資料標誌,一般用於傳輸資料

f=fin   關閉連線標誌,一般用於關閉tcp連線

ack     表示應答包

rst= reset  異常關閉連線

.表示沒有任何標誌

原始碼實現

用於mysql認證**主要集中在函式native_password_authenticate中,具體呼叫層次為:login_connection->check_connection

->acl_authenticate->

do_auth_once->native_password_authenticate,函式邏輯很簡單,就是呼叫write_packet往客戶端發乙個認證包,然後呼叫read_packet等待客戶端返回包含使用者名稱、密碼等資訊的包,最後解析包中的資訊進行密碼驗證,成功後,會在呼叫protocol::send_ok發乙個認證成功網路包,這個過程可以在圖中的第二步全部體現。底層socket通訊**主要集中在sql/net_serv.cc中,具體而言讀採用介面my_net_read,寫採用介面my_net_write。 問題

(1).unix socket方式登陸與tcp方式登陸有什麼區別和聯絡?

unix socket是實現程序間通訊的一種方式,mysql支援利用unix socket來實現客戶端-服務端的通訊,但要求客戶端和服務端在同一臺機器上。對於unix socket而言,同樣也是一種套接字,監聽執行緒會同時監聽tcp socket和unix socket,接受到請求然後處理,後續的處理邏輯都是一致的,只不過底層通訊方式不一樣罷了。

mysql  -h127.0.0.1 –p3306 –u*** –p***  [

tcp通訊方式

]mysql

-u*** –p*** –s/usr/mysql/mysql.sock [

unix socket通訊方式

]

(2).

監聽socket是否與通訊socket公用乙個埠?

我們知道,服務端一直有乙個監聽socket在3306埠監聽,等待新進來的客戶請求,一旦乙個請求過來,服務端會重新建立乙個新的通訊socket,這個新的socket專門用於與這個客戶通訊,而監聽socket則繼續監聽。雖然是2個套接字,但監聽socket和通訊socket都是同乙個埠,通過netstat可以確認這個問題。

(3).連線超時引數connect_timeout在何時作用?

這個引數實質就是在mysql認證過程起作用,如果在這個過程中,客戶端超過connect_timeout時間仍然沒有傳送密碼認證包過來,則會主動斷開連線。

參考文件

spring mvc 原理深度解析

概要 spring mvc 設計思想與體系結構組成 mvc 執行流程解析 註解配置 jsp 執行過程回顧 spring mvc執行流程解析 mvc 體系結構 流程說明 請求servlet 處理業務邏輯 設定業務model forward jsp servlet jsp servlet 解析封裝htm...

深度解析 Condition實現原理

condition指的就是conditionobject,是aqs的乙個內部類。conditionobject的原理是基於aqs的node內部類維護了兩個佇列,乙個等待佇列,乙個同步佇列 乙個是單向佇列,乙個是雙向佇列。如果某個執行緒呼叫了await方法之後,就會使當前執行緒進入到等待狀態,原理就是...

深度解析執行緒工作原理

1,執行緒的概念 乙個程式中的方法有幾條執行路徑,就有幾個執行緒 2,執行緒的建立 兩種方式 1,繼承thread class testthread extends thread 2,實現runnable介面,然後作為引數傳入到thread類的構造方法中 class testthread imple...