結(jié)論:如果結(jié)果集大小超過TCP MSS(MAX SEGMENT SIZE),將會(huì)分批將結(jié)果集返回給客戶端。
實(shí)驗(yàn)過程如下(除了驗(yàn)證分批傳輸以外,還有列出和mysql交互過程中的其他抓包):
這里使用的mysql客戶端是mycli,您可以自行安裝下載。
連接mysql:
mycli -h 10.16.208.21 -P 3321 -u root -p
Password:
以下是連接mysql的抓包過程(還沒有輸入密碼):
可以看到在輸入密碼之前,mysql server最后發(fā)出了FIN,主動(dòng)斷開客戶端的連接,感覺應(yīng)該是為了在沒有獲取登錄權(quán)限以前,盡量不占用server資源。

查詢數(shù)據(jù):

No 530: 客戶端向mysql server發(fā)送查詢請求,查詢語句如下:
select * from customer_favorite_search limit 100;
No 531-566: mysql server端向客戶端分批發(fā)送結(jié)果集,同時(shí)客戶端收到消息后,進(jìn)行ACK確認(rèn)。
自問自答:
這里需要注意的是,mysql server端每次向客戶端發(fā)送數(shù)據(jù)的長度最大為1448,最后一次發(fā)送數(shù)據(jù)的長度941。這里我們可能有些疑問,為什么偏偏是1448,這個(gè)數(shù)據(jù)是怎么確定下來的呢?
原因是這樣的:
數(shù)據(jù)鏈路層傳輸?shù)膸笮∈怯邢拗频?,不能把一個(gè)太大的包直接塞給鏈路層,這個(gè)限制被稱為「最大傳輸單元(Maximum Transmission Unit, MTU)」
下圖是以太網(wǎng)的幀格式,以太網(wǎng)的幀最小的幀是 64 字節(jié),除去 14 字節(jié)頭部和 4 字節(jié) CRC 字段,有效荷載最小為 46 字節(jié)。最大的幀是 1518 字節(jié),除去 14 字節(jié)頭部和 4 字節(jié) CRC,有效荷載最大為 1500,這個(gè)值就是以太網(wǎng)的 MTU。因此如果傳輸 100KB 的數(shù)據(jù),至少需要 (100 * 1024 / 1500) = 69 個(gè)以太網(wǎng)幀。

參考:https://juejin.cn/book/6844733788681928712/section/6844733788816179207
不同的數(shù)據(jù)鏈路層的 MTU 是不同的。通過netstat -i 可以查看網(wǎng)卡的 mtu,如下是我mac電腦的信息:
image.png
回到正題:
1448 = 1500(以太網(wǎng) MTU) - 20(IP 固定表頭大小) - 20(TCP 固定表頭大?。?- 12(TCP 表頭選項(xiàng))
image.png
從上面的過程,我們可以得出以下結(jié)論:
- mysql server和客戶端數(shù)據(jù)交互采用的是TCP協(xié)議
- 如果結(jié)果集大約MTU時(shí),客戶端將會(huì)分批獲取到數(shù)據(jù)
其實(shí)到目前為止,我們沒有充分證明,mysql是將結(jié)果集一次性返回給客戶端的,只能充TCP傳輸上看,客戶端是分批獲取到的。
擴(kuò)展:
mysql的軟件架構(gòu)里面,分配sever層和存儲(chǔ)引擎層,server層和存儲(chǔ)引擎層的交互是以記錄為單位,對于innodb存儲(chǔ)引擎層來說,其和存儲(chǔ)設(shè)備之間是以頁為單位進(jìn)行交互的。innodb引擎按照server層的要求從數(shù)據(jù)中找到符合條件的,并返回給server層,server層判斷是否符合查詢要求,如果符合,就將該數(shù)據(jù)發(fā)送到socket緩沖區(qū)中,然后繼續(xù)向innodb引擎要下一條數(shù)據(jù),指導(dǎo)第一條數(shù)據(jù)不滿足條件的數(shù)據(jù)出現(xiàn)。但是socket緩沖區(qū)的數(shù)據(jù)何時(shí)發(fā)送給客戶端,這個(gè)時(shí)機(jī)有操作系統(tǒng)決定,并不再受mysql的控制。
其實(shí)流程就是這樣的:mysql server判斷存儲(chǔ)引擎給的數(shù)據(jù)是否符合查詢要求,如果符合就將該條記錄發(fā)送到socket緩沖區(qū)中,如果如何條件的記錄有100條,那么server層向socket緩沖區(qū)發(fā)送數(shù)據(jù)的過程就有100次,然后由操作系統(tǒng)決定何時(shí)將緩沖區(qū)的數(shù)據(jù)發(fā)送到對端。

