日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

MySQL协议分析

發(fā)布時(shí)間:2024/9/30 数据库 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL协议分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1 交互過(guò)程

MySQL客戶(hù)端與服務(wù)器的交互主要分為兩個(gè)階段:握手認(rèn)證階段和命令執(zhí)行階段。

1.1 握手認(rèn)證階段

握手認(rèn)證階段為客戶(hù)端與服務(wù)器建立連接后進(jìn)行,交互過(guò)程如下:

  • 服務(wù)器 -> 客戶(hù)端:握手初始化消息
  • 客戶(hù)端 -> 服務(wù)器:登陸認(rèn)證消息
  • 服務(wù)器 -> 客戶(hù)端:認(rèn)證結(jié)果消息

1.2 命令執(zhí)行階段

客戶(hù)端認(rèn)證成功后,會(huì)進(jìn)入命令執(zhí)行階段,交互過(guò)程如下:

  • 客戶(hù)端 -> 服務(wù)器:執(zhí)行命令消息
  • 服務(wù)器 -> 客戶(hù)端:命令執(zhí)行結(jié)果

MySQL客戶(hù)端與服務(wù)器的完整交互過(guò)程如下

2 基本類(lèi)型

2.1 整型值

MySQL報(bào)文中整型值分別有1、2、3、4、8字節(jié)長(zhǎng)度,使用小字節(jié)序傳輸。

2.2 字符串(以NULL結(jié)尾)(Null-Terminated String)

字符串長(zhǎng)度不固定,當(dāng)遇到'NULL'(0x00)字符時(shí)結(jié)束。

2.3 二進(jìn)制數(shù)據(jù)(長(zhǎng)度編碼)(Length Coded Binary)

數(shù)據(jù)長(zhǎng)度不固定,長(zhǎng)度值由數(shù)據(jù)前的1-9個(gè)字節(jié)決定,其中長(zhǎng)度值所占的字節(jié)數(shù)不定,字節(jié)數(shù)由第1個(gè)字節(jié)決定,如下表:

第一個(gè)字節(jié)值 后續(xù)字節(jié)數(shù) 長(zhǎng)度值說(shuō)明
0-250 0 第一個(gè)字節(jié)值即為數(shù)據(jù)的真實(shí)長(zhǎng)度
251 0 空數(shù)據(jù),數(shù)據(jù)的真實(shí)長(zhǎng)度為零
252 2 后續(xù)額外2個(gè)字節(jié)標(biāo)識(shí)了數(shù)據(jù)的真實(shí)長(zhǎng)度
253 3 后續(xù)額外3個(gè)字節(jié)標(biāo)識(shí)了數(shù)據(jù)的真實(shí)長(zhǎng)度
254 8 后續(xù)額外8個(gè)字節(jié)標(biāo)識(shí)了數(shù)據(jù)的真實(shí)長(zhǎng)度

2.4 字符串(長(zhǎng)度編碼)(Length Coded String)

字符串長(zhǎng)度不固定,無(wú)'NULL'(0x00)結(jié)束符,編碼方式與上面的 Length Coded Binary 相同。

3 報(bào)文結(jié)構(gòu)

報(bào)文分為消息頭和消息體兩部分,其中消息頭占用固定的4個(gè)字節(jié),消息體長(zhǎng)度由消息頭中的長(zhǎng)度字段決定,報(bào)文結(jié)構(gòu)如下:

3.1 消息頭

3.1.1 報(bào)文長(zhǎng)度

用于標(biāo)記當(dāng)前請(qǐng)求消息的實(shí)際數(shù)據(jù)長(zhǎng)度值,以字節(jié)為單位,占用3個(gè)字節(jié),最大值為 0xFFFFFF,即接近 16 MB 大小(比16MB少1個(gè)字節(jié))。

3.1.2 序號(hào)

在一次完整的請(qǐng)求/響應(yīng)交互過(guò)程中,用于保證消息順序的正確,每次客戶(hù)端發(fā)起請(qǐng)求時(shí),序號(hào)值都會(huì)從0開(kāi)始計(jì)算。

3.2 消息體

消息體用于存放請(qǐng)求的內(nèi)容及響應(yīng)的數(shù)據(jù),長(zhǎng)度由消息頭中的長(zhǎng)度值決定。

4 報(bào)文類(lèi)型

4.1 登陸認(rèn)證交互報(bào)文

4.1.1 握手初始化報(bào)文(服務(wù)器 -> 客戶(hù)端)

服務(wù)協(xié)議版本號(hào):該值由 PROTOCOL_VERSION 宏定義決定(參考MySQL源代碼/include/mysql_version.h頭文件定義)

服務(wù)版本信息:該值為字符串,由 MYSQL_SERVER_VERSION 宏定義決定(參考MySQL源代碼/include/mysql_version.h頭文件定義)

服務(wù)器線(xiàn)程ID:服務(wù)器為當(dāng)前連接所創(chuàng)建的線(xiàn)程ID。

挑戰(zhàn)隨機(jī)數(shù):MySQL數(shù)據(jù)庫(kù)用戶(hù)認(rèn)證采用的是挑戰(zhàn)/應(yīng)答的方式,服務(wù)器生成該挑戰(zhàn)數(shù)并發(fā)送給客戶(hù)端,由客戶(hù)端進(jìn)行處理并返回相應(yīng)結(jié)果,然后服務(wù)器檢查是否與預(yù)期的結(jié)果相同,從而完成用戶(hù)認(rèn)證的過(guò)程。

服務(wù)器權(quán)能標(biāo)志:用于與客戶(hù)端協(xié)商通訊方式,各標(biāo)志位含義如下(參考MySQL源代碼/include/mysql_com.h中的宏定義):

標(biāo)志位名稱(chēng) 標(biāo)志位 說(shuō)明
CLIENT_LONG_PASSWORD 0x0001 new more secure passwords
CLIENT_FOUND_ROWS 0x0002 Found instead of affected rows
CLIENT_LONG_FLAG 0x0004 Get all column flags
CLIENT_CONNECT_WITH_DB 0x0008 One can specify db on connect
CLIENT_NO_SCHEMA 0x0010 Do not allow database.table.column
CLIENT_COMPRESS 0x0020 Can use compression protocol
CLIENT_ODBC 0x0040 Odbc client
CLIENT_LOCAL_FILES 0x0080 Can use LOAD DATA LOCAL
CLIENT_IGNORE_SPACE 0x0100 Ignore spaces before '('
CLIENT_PROTOCOL_41 0x0200 New 4.1 protocol
CLIENT_INTERACTIVE 0x0400 This is an interactive client
CLIENT_SSL 0x0800 Switch to SSL after handshake
CLIENT_IGNORE_SIGPIPE 0x1000 IGNORE sigpipes
CLIENT_TRANSACTIONS 0x2000 Client knows about transactions
CLIENT_RESERVED 0x4000 Old flag for 4.1 protocol
CLIENT_SECURE_CONNECTION 0x8000 New 4.1 authentication
CLIENT_MULTI_STATEMENTS 0x0001 0000 Enable/disable multi-stmt support
CLIENT_MULTI_RESULTS 0x0002 0000 Enable/disable multi-results

字符編碼:標(biāo)識(shí)服務(wù)器所使用的字符集。

服務(wù)器狀態(tài):狀態(tài)值定義如下(參考MySQL源代碼/include/mysql_com.h中的宏定義):

狀態(tài)名稱(chēng) 狀態(tài)值
SERVER_STATUS_IN_TRANS 0x0001
SERVER_STATUS_AUTOCOMMIT 0x0002
SERVER_STATUS_CURSOR_EXISTS 0x0040
SERVER_STATUS_LAST_ROW_SENT 0x0080
SERVER_STATUS_DB_DROPPED 0x0100
SERVER_STATUS_NO_BACKSLASH_ESCAPES 0x0200
SERVER_STATUS_METADATA_CHANGED 0x0400

4.1.2 登陸認(rèn)證報(bào)文(客戶(hù)端 -> 服務(wù)器)

MySQL 4.0 及之前的版本

MySQL 4.1 及之后的版本

客戶(hù)端權(quán)能標(biāo)志:用于與客戶(hù)端協(xié)商通訊方式,標(biāo)志位含義與握手初始化報(bào)文中的相同。客戶(hù)端收到服務(wù)器發(fā)來(lái)的初始化報(bào)文后,會(huì)對(duì)服務(wù)器發(fā)送的權(quán)能標(biāo)志進(jìn)行修改,保留自身所支持的功能,然后將權(quán)能標(biāo)返回給服務(wù)器,從而保證服務(wù)器與客戶(hù)端通訊的兼容性。

最大消息長(zhǎng)度:客戶(hù)端發(fā)送請(qǐng)求報(bào)文時(shí)所支持的最大消息長(zhǎng)度值。

字符編碼:標(biāo)識(shí)通訊過(guò)程中使用的字符編碼,與服務(wù)器在認(rèn)證初始化報(bào)文中發(fā)送的相同。

用戶(hù)名:客戶(hù)端登陸用戶(hù)的用戶(hù)名稱(chēng)。

挑戰(zhàn)認(rèn)證數(shù)據(jù):客戶(hù)端用戶(hù)密碼使用服務(wù)器發(fā)送的挑戰(zhàn)隨機(jī)數(shù)進(jìn)行加密后,生成挑戰(zhàn)認(rèn)證數(shù)據(jù),然后返回給服務(wù)器,用于對(duì)用戶(hù)身份的認(rèn)證。

數(shù)據(jù)庫(kù)名稱(chēng):當(dāng)客戶(hù)端的權(quán)能標(biāo)志位 CLIENT_CONNECT_WITH_DB 被置位時(shí),該字段必須出現(xiàn)。

4.2 客戶(hù)端命令請(qǐng)求報(bào)文(客戶(hù)端 -> 服務(wù)器)

命令:用于標(biāo)識(shí)當(dāng)前請(qǐng)求消息的類(lèi)型,例如切換數(shù)據(jù)庫(kù)(0x02)、查詢(xún)命令(0x03)等。命令值的取值范圍及說(shuō)明如下表(參考MySQL源代碼/include/mysql_com.h頭文件中的定義):

類(lèi)型值 命令 功能 關(guān)聯(lián)函數(shù)
0x00 COM_SLEEP (內(nèi)部線(xiàn)程狀態(tài)) (無(wú))
0x01 COM_QUIT 關(guān)閉連接 mysql_close
0x02 COM_INIT_DB 切換數(shù)據(jù)庫(kù) mysql_select_db
0x03 COM_QUERY SQL查詢(xún)請(qǐng)求 mysql_real_query
0x04 COM_FIELD_LIST 獲取數(shù)據(jù)表字段信息 mysql_list_fields
0x05 COM_CREATE_DB 創(chuàng)建數(shù)據(jù)庫(kù) mysql_create_db
0x06 COM_DROP_DB 刪除數(shù)據(jù)庫(kù) mysql_drop_db
0x07 COM_REFRESH 清除緩存 mysql_refresh
0x08 COM_SHUTDOWN 停止服務(wù)器 mysql_shutdown
0x09 COM_STATISTICS 獲取服務(wù)器統(tǒng)計(jì)信息 mysql_stat
0x0A COM_PROCESS_INFO 獲取當(dāng)前連接的列表 mysql_list_processes
0x0B COM_CONNECT (內(nèi)部線(xiàn)程狀態(tài)) (無(wú))
0x0C COM_PROCESS_KILL 中斷某個(gè)連接 mysql_kill
0x0D COM_DEBUG 保存服務(wù)器調(diào)試信息 mysql_dump_debug_info
0x0E COM_PING 測(cè)試連通性 mysql_ping
0x0F COM_TIME (內(nèi)部線(xiàn)程狀態(tài)) (無(wú))
0x10 COM_DELAYED_INSERT (內(nèi)部線(xiàn)程狀態(tài)) (無(wú))
0x11 COM_CHANGE_USER 重新登陸(不斷連接) mysql_change_user
0x12 COM_BINLOG_DUMP 獲取二進(jìn)制日志信息 (無(wú))
0x13 COM_TABLE_DUMP 獲取數(shù)據(jù)表結(jié)構(gòu)信息 (無(wú))
0x14 COM_CONNECT_OUT (內(nèi)部線(xiàn)程狀態(tài)) (無(wú))
0x15 COM_REGISTER_SLAVE 從服務(wù)器向主服務(wù)器進(jìn)行注冊(cè) (無(wú))
0x16 COM_STMT_PREPARE 預(yù)處理SQL語(yǔ)句 mysql_stmt_prepare
0x17 COM_STMT_EXECUTE 執(zhí)行預(yù)處理語(yǔ)句 mysql_stmt_execute
0x18 COM_STMT_SEND_LONG_DATA 發(fā)送BLOB類(lèi)型的數(shù)據(jù) mysql_stmt_send_long_data
0x19 COM_STMT_CLOSE 銷(xiāo)毀預(yù)處理語(yǔ)句 mysql_stmt_close
0x1A COM_STMT_RESET 清除預(yù)處理語(yǔ)句參數(shù)緩存 mysql_stmt_reset
0x1B COM_SET_OPTION 設(shè)置語(yǔ)句選項(xiàng) mysql_set_server_option
0x1C COM_STMT_FETCH 獲取預(yù)處理語(yǔ)句的執(zhí)行結(jié)果 mysql_stmt_fetch

參數(shù):內(nèi)容是用戶(hù)在MySQL客戶(hù)端輸入的命令(不包括每行命令結(jié)尾的";"分號(hào))。另外這個(gè)字段的字符串不是以NULL字符結(jié)尾,而是通過(guò)消息頭中的長(zhǎng)度值計(jì)算而來(lái)。

例如:當(dāng)我們?cè)贛ySQL客戶(hù)端中執(zhí)行use hutaow;命令時(shí)(切換到hutaow數(shù)據(jù)庫(kù)),發(fā)送的請(qǐng)求報(bào)文數(shù)據(jù)會(huì)是下面的樣子:

0x02 0x68 0x75 0x74 0x61 0x6f 0x77

其中,0x02為請(qǐng)求類(lèi)型值COM_INIT_DB,后面的0x68 0x75 0x74 0x61 0x6f 0x77為ASCII字符hutaow。

4.2.1 COM_QUIT 消息報(bào)文

功能:關(guān)閉當(dāng)前連接(客戶(hù)端退出),無(wú)參數(shù)。

4.2.2 COM_INIT_DB 消息報(bào)文

功能:切換數(shù)據(jù)庫(kù),對(duì)應(yīng)的SQL語(yǔ)句為USE <database>。

字節(jié) 說(shuō)明
n 數(shù)據(jù)庫(kù)名稱(chēng)(字符串到達(dá)消息尾部時(shí)結(jié)束,無(wú)結(jié)束符)

4.2.3 COM_QUERY 消息報(bào)文

功能:最常見(jiàn)的請(qǐng)求消息類(lèi)型,當(dāng)用戶(hù)執(zhí)行SQL語(yǔ)句時(shí)發(fā)送該消息。

字節(jié) 說(shuō)明
n SQL語(yǔ)句(字符串到達(dá)消息尾部時(shí)結(jié)束,無(wú)結(jié)束符)

4.2.4 COM_FIELD_LIST 消息報(bào)文

功能:查詢(xún)某表的字段(列)信息,等同于SQL語(yǔ)句SHOW [FULL] FIELDS FROM ...。

字節(jié) 說(shuō)明
n 表格名稱(chēng)(Null-Terminated String)
n 字段(列)名稱(chēng)或通配符(可選)

4.2.5 COM_CREATE_DB 消息報(bào)文

功能:創(chuàng)建數(shù)據(jù)庫(kù),該消息已過(guò)時(shí),而被SQL語(yǔ)句CREATE DATABASE代替。

字節(jié) 說(shuō)明
n 數(shù)據(jù)庫(kù)名稱(chēng)(字符串到達(dá)消息尾部時(shí)結(jié)束,無(wú)結(jié)束符)

4.2.6 COM_DROP_DB 消息報(bào)文

功能:刪除數(shù)據(jù)庫(kù),該消息已過(guò)時(shí),而被SQL語(yǔ)句DROP DATABASE代替。

字節(jié) 說(shuō)明
n 數(shù)據(jù)庫(kù)名稱(chēng)(字符串到達(dá)消息尾部時(shí)結(jié)束,無(wú)結(jié)束符)

4.2.7 COM_REFRESH 消息報(bào)文

功能:清除緩存,等同于SQL語(yǔ)句FLUSH,或是執(zhí)行mysqladmin flush-foo命令時(shí)發(fā)送該消息。

字節(jié) 說(shuō)明
1 清除緩存選項(xiàng)(位圖方式存儲(chǔ),各標(biāo)志位含義如下)
? 0x01: REFRESH_GRANT
? 0x02: REFRESH_LOG
? 0x04: REFRESH_TABLES
? 0x08: REFRESH_HOSTS
? 0x10: REFRESH_STATUS
? 0x20: REFRESH_THREADS
? 0x40: REFRESH_SLAVE
? 0x80: REFRESH_MASTER

4.2.8 COM_SHUTDOWN 消息報(bào)文

功能:停止MySQL服務(wù)。執(zhí)行mysqladmin shutdown命令時(shí)發(fā)送該消息。

字節(jié) 說(shuō)明
1 停止服務(wù)選項(xiàng)
? 0x00: SHUTDOWN_DEFAULT
? 0x01: SHUTDOWN_WAIT_CONNECTIONS
? 0x02: SHUTDOWN_WAIT_TRANSACTIONS
? 0x08: SHUTDOWN_WAIT_UPDATES
? 0x10: SHUTDOWN_WAIT_ALL_BUFFERS
? 0x11: SHUTDOWN_WAIT_CRITICAL_BUFFERS
? 0xFE: KILL_QUERY
? 0xFF: KILL_CONNECTION

4.2.9 COM_STATISTICS 消息報(bào)文

功能:查看MySQL服務(wù)的統(tǒng)計(jì)信息(例如運(yùn)行時(shí)間、每秒查詢(xún)次數(shù)等)。執(zhí)行mysqladmin status命令時(shí)發(fā)送該消息,無(wú)參數(shù)。

4.2.10 COM_PROCESS_INFO 消息報(bào)文

功能:獲取當(dāng)前活動(dòng)的線(xiàn)程(連接)列表。等同于SQL語(yǔ)句SHOW PROCESSLIST,或是執(zhí)行mysqladmin processlist命令時(shí)發(fā)送該消息,無(wú)參數(shù)。

4.2.11 COM_PROCESS_KILL 消息報(bào)文

功能:要求服務(wù)器中斷某個(gè)連接。等同于SQL語(yǔ)句KILL <id>。

字節(jié) 說(shuō)明
4 連接ID號(hào)(小字節(jié)序)

4.2.12 COM_DEBUG 消息報(bào)文

功能:要求服務(wù)器將調(diào)試信息保存下來(lái),保存的信息多少依賴(lài)于編譯選項(xiàng)設(shè)置(debug=no|yes|full)。執(zhí)行mysqladmin debug命令時(shí)發(fā)送該消息,無(wú)參數(shù)。

4.2.13 COM_PING 消息報(bào)文

功能:該消息用來(lái)測(cè)試連通性,同時(shí)會(huì)將服務(wù)器的無(wú)效連接(超時(shí))計(jì)數(shù)器清零。執(zhí)行mysqladmin ping命令時(shí)發(fā)送該消息,無(wú)參數(shù)。

4.2.14 COM_CHANGE_USER 消息報(bào)文

功能:在不斷連接的情況下重新登陸,該操作會(huì)銷(xiāo)毀MySQL服務(wù)器端的會(huì)話(huà)上下文(包括臨時(shí)表、會(huì)話(huà)變量等)。有些連接池用這種方法實(shí)現(xiàn)清除會(huì)話(huà)上下文。

字節(jié) 說(shuō)明
n 用戶(hù)名(字符串以NULL結(jié)尾)
n 密碼(挑戰(zhàn)數(shù))
? MySQL 3.23 版本:Null-Terminated String(長(zhǎng)度9字節(jié))
? MySQL 4.1 版本:Length Coded String(長(zhǎng)度1+21字節(jié))
n 數(shù)據(jù)庫(kù)名稱(chēng)(Null-Terminated String)
2 字符編碼

4.2.15 COM_BINLOG_DUMP 消息報(bào)文

功能:該消息是備份連接時(shí)由從服務(wù)器向主服務(wù)器發(fā)送的最后一個(gè)請(qǐng)求,主服務(wù)器收到后,會(huì)響應(yīng)一系列的報(bào)文,每個(gè)報(bào)文都包含一個(gè)二進(jìn)制日志事件。如果主服務(wù)器出現(xiàn)故障時(shí),會(huì)發(fā)送一個(gè)EOF報(bào)文。

字節(jié) 說(shuō)明
4 二進(jìn)制日志數(shù)據(jù)的起始位置(小字節(jié)序)
4 二進(jìn)制日志數(shù)據(jù)標(biāo)志位(目前未使用,永遠(yuǎn)為0x00)
4 從服務(wù)器的服務(wù)器ID值(小字節(jié)序)
n 二進(jìn)制日志的文件名稱(chēng)(可選,默認(rèn)值為主服務(wù)器上第一個(gè)有效的文件名)

4.2.16 COM_TABLE_DUMP 消息報(bào)文

功能:將數(shù)據(jù)表從主服務(wù)器復(fù)制到從服務(wù)器中,執(zhí)行SQL語(yǔ)句LOAD TABLE ... FROM MASTER時(shí)發(fā)送該消息。目前該消息已過(guò)時(shí),不再使用。

字節(jié) 說(shuō)明
n 數(shù)據(jù)庫(kù)名稱(chēng)(Length Coded String)
n 數(shù)據(jù)表名稱(chēng)(Length Coded String)

4.2.17 COM_REGISTER_SLAVE 消息報(bào)文

功能:在從服務(wù)器report_host變量設(shè)置的情況下,當(dāng)備份連接時(shí)向主服務(wù)器發(fā)送的注冊(cè)消息。

字節(jié) 說(shuō)明
4 從服務(wù)器ID值(小字節(jié)序)
n 主服務(wù)器IP地址(Length Coded String)
n 主服務(wù)器用戶(hù)名(Length Coded String)
n 主服務(wù)器密碼(Length Coded String)
2 主服務(wù)器端口號(hào)
4 安全備份級(jí)別(由MySQL服務(wù)器rpl_recovery_rank變量設(shè)置,暫時(shí)未使用)
4 主服務(wù)器ID值(值恒為0x00)

4.2.18 COM_PREPARE 消息報(bào)文

功能:預(yù)處理SQL語(yǔ)句,使用帶有"?"占位符的SQL語(yǔ)句時(shí)發(fā)送該消息。

字節(jié) 說(shuō)明
n 帶有"?"占位符的SQL語(yǔ)句(字符串到達(dá)消息尾部時(shí)結(jié)束,無(wú)結(jié)束符)

4.2.19 COM_EXECUTE 消息報(bào)文

功能:執(zhí)行預(yù)處理語(yǔ)句。

字節(jié) 說(shuō)明
4 預(yù)處理語(yǔ)句的ID值
1 標(biāo)志位
? 0x00: CURSOR_TYPE_NO_CURSOR
? 0x01: CURSOR_TYPE_READ_ONLY
? 0x02: CURSOR_TYPE_FOR_UPDATE
? 0x04: CURSOR_TYPE_SCROLLABLE
4 保留(值恒為0x01)
如果參數(shù)數(shù)量大于0 ?
n 空位圖(Null-Bitmap,長(zhǎng)度 = (參數(shù)數(shù)量 + 7) / 8 字節(jié))
1 參數(shù)分隔標(biāo)志
如果參數(shù)分隔標(biāo)志值為1 ?
n 每個(gè)參數(shù)的類(lèi)型值(長(zhǎng)度 = 參數(shù)數(shù)量 * 2 字節(jié))
n 每個(gè)參數(shù)的值

4.2.20 COM_LONG_DATA 消息報(bào)文

該消息報(bào)文有兩種形式,一種用于發(fā)送二進(jìn)制數(shù)據(jù),另一種用于發(fā)送文本數(shù)據(jù)。

功能:用于發(fā)送二進(jìn)制(BLOB)類(lèi)型的數(shù)據(jù)(調(diào)用mysql_stmt_send_long_data函數(shù))。

字節(jié) 說(shuō)明
4 預(yù)處理語(yǔ)句的ID值(小字節(jié)序)
2 參數(shù)序號(hào)(小字節(jié)序)
n 數(shù)據(jù)負(fù)載(數(shù)據(jù)到達(dá)消息尾部時(shí)結(jié)束,無(wú)結(jié)束符)

功能:用于發(fā)送超長(zhǎng)字符串類(lèi)型的數(shù)據(jù)(調(diào)用mysql_send_long_data函數(shù))

字節(jié) 說(shuō)明
4 預(yù)處理語(yǔ)句的ID值(小字節(jié)序)
2 參數(shù)序號(hào)(小字節(jié)序)
2 數(shù)據(jù)類(lèi)型(未使用)
n 數(shù)據(jù)負(fù)載(數(shù)據(jù)到達(dá)消息尾部時(shí)結(jié)束,無(wú)結(jié)束符)

4.2.21 COM_CLOSE_STMT 消息報(bào)文

功能:銷(xiāo)毀預(yù)處理語(yǔ)句。

字節(jié) 說(shuō)明
4 預(yù)處理語(yǔ)句的ID值(小字節(jié)序)

4.2.22 COM_RESET_STMT 消息報(bào)文

功能:將預(yù)處理語(yǔ)句的參數(shù)緩存清空。多數(shù)情況和COM_LONG_DATA一起使用。

字節(jié) 說(shuō)明
4 預(yù)處理語(yǔ)句的ID值(小字節(jié)序)

4.2.23 COM_SET_OPTION 消息報(bào)文

功能:設(shè)置語(yǔ)句選項(xiàng),選項(xiàng)值為/include/mysql_com.h頭文件中定義的enum_mysql_set_option枚舉類(lèi)型:

  • MYSQL_OPTION_MULTI_STATEMENTS_ON
  • MYSQL_OPTION_MULTI_STATEMENTS_OFF
字節(jié) 說(shuō)明
2 選項(xiàng)值(小字節(jié)序)

4.2.24 COM_FETCH_STMT 消息報(bào)文

功能:獲取預(yù)處理語(yǔ)句的執(zhí)行結(jié)果(一次可以獲取多行數(shù)據(jù))。

字節(jié) 說(shuō)明
4 預(yù)處理語(yǔ)句的ID值(小字節(jié)序)
4 數(shù)據(jù)的行數(shù)(小字節(jié)序)

4.3 服務(wù)器響應(yīng)報(bào)文(服務(wù)器 -> 客戶(hù)端)

當(dāng)客戶(hù)端發(fā)起認(rèn)證請(qǐng)求或命令請(qǐng)求后,服務(wù)器會(huì)返回相應(yīng)的執(zhí)行結(jié)果給客戶(hù)端。客戶(hù)端在收到響應(yīng)報(bào)文后,需要首先檢查第1個(gè)字節(jié)的值,來(lái)區(qū)分響應(yīng)報(bào)文的類(lèi)型。

響應(yīng)報(bào)文類(lèi)型 第1個(gè)字節(jié)取值范圍
OK 響應(yīng)報(bào)文 0x00
Error 響應(yīng)報(bào)文 0xFF
Result Set 報(bào)文 0x01 - 0xFA
Field 報(bào)文 0x01 - 0xFA
Row Data 報(bào)文 0x01 - 0xFA
EOF 報(bào)文 0xFE

注:響應(yīng)報(bào)文的第1個(gè)字節(jié)在不同類(lèi)型中含義不同,比如在OK報(bào)文中,該字節(jié)并沒(méi)有實(shí)際意義,值恒為0x00;而在Result Set報(bào)文中,該字節(jié)又是長(zhǎng)度編碼的二進(jìn)制數(shù)據(jù)結(jié)構(gòu)(Length Coded Binary)中的第1字節(jié)。

4.3.1 OK 響應(yīng)報(bào)文

客戶(hù)端的命令執(zhí)行正確時(shí),服務(wù)器會(huì)返回OK響應(yīng)報(bào)文。

MySQL 4.0 及之前的版本

字節(jié) 說(shuō)明
1 OK報(bào)文,值恒為0x00
1-9 受影響行數(shù)(Length Coded Binary)
1-9 索引ID值(Length Coded Binary)
2 服務(wù)器狀態(tài)
n 服務(wù)器消息(字符串到達(dá)消息尾部時(shí)結(jié)束,無(wú)結(jié)束符)

MySQL 4.1 及之后的版本

字節(jié) 說(shuō)明
1 OK報(bào)文,值恒為0x00
1-9 受影響行數(shù)(Length Coded Binary)
1-9 索引ID值(Length Coded Binary)
2 服務(wù)器狀態(tài)
2 告警計(jì)數(shù)
n 服務(wù)器消息(字符串到達(dá)消息尾部時(shí)結(jié)束,無(wú)結(jié)束符,可選)

受影響行數(shù):當(dāng)執(zhí)行INSERT/UPDATE/DELETE語(yǔ)句時(shí)所影響的數(shù)據(jù)行數(shù)。

索引ID值:該值為AUTO_INCREMENT索引字段生成,如果沒(méi)有索引字段,則為0x00。注意:當(dāng)INSERT插入語(yǔ)句為多行數(shù)據(jù)時(shí),該索引ID值為第一個(gè)插入的數(shù)據(jù)行索引值,而非最后一個(gè)。

服務(wù)器狀態(tài):客戶(hù)端可以通過(guò)該值檢查命令是否在事務(wù)處理中。

告警計(jì)數(shù):告警發(fā)生的次數(shù)。

服務(wù)器消息:服務(wù)器返回給客戶(hù)端的消息,一般為簡(jiǎn)單的描述性字符串,可選字段。

4.3.2 Error 響應(yīng)報(bào)文

MySQL 4.0 及之前的版本

字節(jié) 說(shuō)明
1 Error報(bào)文,值恒為0xFF
2 錯(cuò)誤編號(hào)(小字節(jié)序)
n 服務(wù)器消息

MySQL 4.1 及之后的版本

字節(jié) 說(shuō)明
1 Error報(bào)文,值恒為0xFF
2 錯(cuò)誤編號(hào)(小字節(jié)序)
1 服務(wù)器狀態(tài)標(biāo)志,恒為'#'字符
5 服務(wù)器狀態(tài)(5個(gè)字符)
n 服務(wù)器消息

錯(cuò)誤編號(hào):錯(cuò)誤編號(hào)值定義在源代碼/include/mysqld_error.h頭文件中。

服務(wù)器狀態(tài):服務(wù)器將錯(cuò)誤編號(hào)通過(guò)mysql_errno_to_sqlstate函數(shù)轉(zhuǎn)換為狀態(tài)值,狀態(tài)值由5字節(jié)的ASCII字符組成,定義在源代碼/include/sql_state.h頭文件中。

服務(wù)器消息:錯(cuò)誤消息字符串到達(dá)消息尾時(shí)結(jié)束,長(zhǎng)度可以由消息頭中的長(zhǎng)度值計(jì)算得出。消息長(zhǎng)度為0-512字節(jié)。

4.3.3 Result Set 消息

當(dāng)客戶(hù)端發(fā)送查詢(xún)請(qǐng)求后,在沒(méi)有錯(cuò)誤的情況下,服務(wù)器會(huì)返回結(jié)果集(Result Set)給客戶(hù)端。

Result Set 消息分為五部分,結(jié)構(gòu)如下:

結(jié)構(gòu) 說(shuō)明
[Result Set Header] 列數(shù)量
[Field] 列信息(多個(gè))
[EOF] 列結(jié)束
[Row Data] 行數(shù)據(jù)(多個(gè))
[EOF] 數(shù)據(jù)結(jié)束

4.3.4 Result Set Header 結(jié)構(gòu)

字節(jié) 說(shuō)明
1-9 Field結(jié)構(gòu)計(jì)數(shù)(Length Coded Binary)
1-9 額外信息(Length Coded Binary)

Field結(jié)構(gòu)計(jì)數(shù):用于標(biāo)識(shí)Field結(jié)構(gòu)的數(shù)量,取值范圍0x00-0xFA。

額外信息:可選字段,一般情況下不應(yīng)該出現(xiàn)。只有像SHOW COLUMNS這種語(yǔ)句的執(zhí)行結(jié)果才會(huì)用到額外信息(標(biāo)識(shí)表格的列數(shù)量)。

4.3.5 Field 結(jié)構(gòu)

Field為數(shù)據(jù)表的列信息,在Result Set中,Field會(huì)連續(xù)出現(xiàn)多次,次數(shù)由Result Set Header結(jié)構(gòu)中的IField結(jié)構(gòu)計(jì)數(shù)值決定。

MySQL 4.0 及之前的版本

字節(jié) 說(shuō)明
n 數(shù)據(jù)表名稱(chēng)(Length Coded String)
n 列(字段)名稱(chēng)(Length Coded String)
4 列(字段)長(zhǎng)度(Length Coded String)
2 列(字段)類(lèi)型(Length Coded String)
2 列(字段)標(biāo)志(Length Coded String)
1 整型值精度
n 默認(rèn)值(Length Coded String)

MySQL 4.1 及之后的版本

字節(jié) 說(shuō)明
n 目錄名稱(chēng)(Length Coded String)
n 數(shù)據(jù)庫(kù)名稱(chēng)(Length Coded String)
n 數(shù)據(jù)表名稱(chēng)(Length Coded String)
n 數(shù)據(jù)表原始名稱(chēng)(Length Coded String)
n 列(字段)名稱(chēng)(Length Coded String)
4 列(字段)原始名稱(chēng)(Length Coded String)
1 填充值
2 字符編碼
4 列(字段)長(zhǎng)度
1 列(字段)類(lèi)型
2 列(字段)標(biāo)志
1 整型值精度
2 填充值(0x00)
n 默認(rèn)值(Length Coded String)

目錄名稱(chēng):在4.1及之后的版本中,該字段值為"def"。

數(shù)據(jù)庫(kù)名稱(chēng):數(shù)據(jù)庫(kù)名稱(chēng)標(biāo)識(shí)。

數(shù)據(jù)表名稱(chēng):數(shù)據(jù)表的別名(AS之后的名稱(chēng))。

數(shù)據(jù)表原始名稱(chēng):數(shù)據(jù)表的原始名稱(chēng)(AS之前的名稱(chēng))。

列(字段)名稱(chēng):列(字段)的別名(AS之后的名稱(chēng))。

列(字段)原始名稱(chēng):列(字段)的原始名稱(chēng)(AS之前的名稱(chēng))。

字符編碼:列(字段)的字符編碼值。

列(字段)長(zhǎng)度:列(字段)的長(zhǎng)度值,真實(shí)長(zhǎng)度可能小于該值,例如VARCHAR(2)類(lèi)型的字段實(shí)際只能存儲(chǔ)1個(gè)字符。

列(字段)類(lèi)型:列(字段)的類(lèi)型值,取值范圍如下(參考源代碼/include/mysql_com.h頭文件中的enum_field_type枚舉類(lèi)型定義):

類(lèi)型值 名稱(chēng)
0x00 FIELD_TYPE_DECIMAL
0x01 FIELD_TYPE_TINY
0x02 FIELD_TYPE_SHORT
0x03 FIELD_TYPE_LONG
0x04 FIELD_TYPE_FLOAT
0x05 FIELD_TYPE_DOUBLE
0x06 FIELD_TYPE_NULL
0x07 FIELD_TYPE_TIMESTAMP
0x08 FIELD_TYPE_LONGLONG
0x09 FIELD_TYPE_INT24
0x0A FIELD_TYPE_DATE
0x0B FIELD_TYPE_TIME
0x0C FIELD_TYPE_DATETIME
0x0D FIELD_TYPE_YEAR
0x0E FIELD_TYPE_NEWDATE
0x0F FIELD_TYPE_VARCHAR (new in MySQL 5.0)
0x10 FIELD_TYPE_BIT (new in MySQL 5.0)
0xF6 FIELD_TYPE_NEWDECIMAL (new in MYSQL 5.0)
0xF7 FIELD_TYPE_ENUM
0xF8 FIELD_TYPE_SET
0xF9 FIELD_TYPE_TINY_BLOB
0xFA FIELD_TYPE_MEDIUM_BLOB
0xFB FIELD_TYPE_LONG_BLOB
0xFC FIELD_TYPE_BLOB
0xFD FIELD_TYPE_VAR_STRING
0xFE FIELD_TYPE_STRING
0xFF FIELD_TYPE_GEOMETRY

列(字段)標(biāo)志:各標(biāo)志位定義如下(參考源代碼/include/mysql_com.h頭文件中的宏定義):

標(biāo)志位 名稱(chēng)
0x0001 NOT_NULL_FLAG
0x0002 PRI_KEY_FLAG
0x0004 UNIQUE_KEY_FLAG
0x0008 MULTIPLE_KEY_FLAG
0x0010 BLOB_FLAG
0x0020 UNSIGNED_FLAG
0x0040 ZEROFILL_FLAG
0x0080 BINARY_FLAG
0x0100 ENUM_FLAG
0x0200 AUTO_INCREMENT_FLAG
0x0400 TIMESTAMP_FLAG
0x0800 SET_FLAG

數(shù)值精度:該字段對(duì)DECIMAL和NUMERIC類(lèi)型的數(shù)值字段有效,用于標(biāo)識(shí)數(shù)值的精度(小數(shù)點(diǎn)位置)。

默認(rèn)值:該字段用在數(shù)據(jù)表定義中,普通的查詢(xún)結(jié)果中不會(huì)出現(xiàn)。

:Field結(jié)構(gòu)的相關(guān)處理函數(shù):

  • 客戶(hù)端:/client/client.c源文件中的unpack_fields函數(shù)
  • 服務(wù)器:/sql/sql_base.cc源文件中的send_fields函數(shù)

4.3.6 EOF 結(jié)構(gòu)

EOF結(jié)構(gòu)用于標(biāo)識(shí)Field和Row Data的結(jié)束,在預(yù)處理語(yǔ)句中,EOF也被用來(lái)標(biāo)識(shí)參數(shù)的結(jié)束。

MySQL 4.0 及之前的版本

字節(jié) 說(shuō)明
1 EOF值(0xFE)

MySQL 4.1 及之后的版本

字節(jié) 說(shuō)明
1 EOF值(0xFE)
2 告警計(jì)數(shù)
2 狀態(tài)標(biāo)志位

告警計(jì)數(shù):服務(wù)器告警數(shù)量,在所有數(shù)據(jù)都發(fā)送給客戶(hù)端后該值才有效。

狀態(tài)標(biāo)志位:包含類(lèi)似SERVER_MORE_RESULTS_EXISTS這樣的標(biāo)志位。

:由于EOF值與其它Result Set結(jié)構(gòu)共用1字節(jié),所以在收到報(bào)文后需要對(duì)EOF包的真實(shí)性進(jìn)行校驗(yàn),校驗(yàn)條件為:

  • 第1字節(jié)值為0xFE
  • 包長(zhǎng)度小于9字節(jié)

:EOF結(jié)構(gòu)的相關(guān)處理函數(shù):

  • 服務(wù)器:protocol.cc源文件中的send_eof函數(shù)

4.3.7 Row Data 結(jié)構(gòu)

在Result Set消息中,會(huì)包含多個(gè)Row Data結(jié)構(gòu),每個(gè)Row Data結(jié)構(gòu)又包含多個(gè)字段值,這些字段值組成一行數(shù)據(jù)。

字節(jié) 說(shuō)明
n 字段值(Length Coded String)
... (一行數(shù)據(jù)中包含多個(gè)字段值)

字段值:行數(shù)據(jù)中的字段值,字符串形式。

:Row Data結(jié)構(gòu)的相關(guān)處理函數(shù):

  • 客戶(hù)端:/client/client.c源文件中的read_rows函數(shù)

4.3.8 Row Data 結(jié)構(gòu)(二進(jìn)制數(shù)據(jù))

該結(jié)構(gòu)用于傳輸二進(jìn)制的字段值,既可以是服務(wù)器返回的結(jié)果,也可以是由客戶(hù)端發(fā)送的(當(dāng)執(zhí)行預(yù)處理語(yǔ)句時(shí),客戶(hù)端使用Result Set消息來(lái)發(fā)送參數(shù)及數(shù)據(jù))。

字節(jié) 說(shuō)明
1 結(jié)構(gòu)頭(0x00)
(列數(shù)量 + 7 + 2) / 8 空位圖
n 字段值
... (一行數(shù)據(jù)中包含多個(gè)字段值)

空位圖:前2個(gè)比特位被保留,值分別為0和1,以保證不會(huì)和OK、Error包的首字節(jié)沖突。在MySQL 5.0及之后的版本中,這2個(gè)比特位的值都為0。

字段值:行數(shù)據(jù)中的字段值,二進(jìn)制形式。

4.3.9 PREPARE_OK 響應(yīng)報(bào)文(Prepared Statement)

用于響應(yīng)客戶(hù)端發(fā)起的預(yù)處理語(yǔ)句報(bào)文,組成結(jié)構(gòu)如下:

結(jié)構(gòu) 說(shuō)明
[PREPARE_OK] PREPARE_OK結(jié)構(gòu)
如果參數(shù)數(shù)量大于0 ?
[Field] 與Result Set消息結(jié)構(gòu)相同
[EOF] ?
如果列數(shù)大于0 ?
[Field] 與Result Set消息結(jié)構(gòu)相同
[EOF] ?

其中 PREPARD_OK 的結(jié)構(gòu)如下:

字節(jié) 說(shuō)明
1 OK報(bào)文,值為0x00
4 預(yù)處理語(yǔ)句ID值
2 列數(shù)量
2 參數(shù)數(shù)量
1 填充值(0x00)
2 告警計(jì)數(shù)

4.3.10 Parameter 響應(yīng)報(bào)文(Prepared Statement)

預(yù)處理語(yǔ)句的值與參數(shù)正確對(duì)應(yīng)后,服務(wù)器會(huì)返回 Parameter 報(bào)文。

字節(jié) 說(shuō)明
2 類(lèi)型
2 標(biāo)志
1 數(shù)值精度
4 字段長(zhǎng)度

類(lèi)型:與 Field 結(jié)構(gòu)中的字段類(lèi)型相同。

標(biāo)志:與 Field 結(jié)構(gòu)中的字段標(biāo)志相同。

數(shù)值精度:與 Field 結(jié)構(gòu)中的數(shù)值精度相同。

字段長(zhǎng)度:與 Field 結(jié)構(gòu)中的字段長(zhǎng)度相同。

5 參考資料

《MySQL Internals Manual:?MySQL Client/Server Protocol》

總結(jié)

以上是生活随笔為你收集整理的MySQL协议分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。