深度解析MySQL登入原理

來源:互聯網
上載者:User

深度解析MySQL登入原理

使用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 –uxxx –pxxx

登陸成功後,然後直接執行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 –uxxx –pxxx  [TCP通訊方式]
mysql  -uxxx –pxxx –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時間仍然沒有發送密碼認證包過來,則會主動中斷連線。

本文永久更新連結地址:

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.