网站禁止访问,湖南宁乡建设局网站,如何做网站联盟营销,做网站放太多视频MySQL 8 版本中的客户端-服务器通信相关#xff0c;特别是在接收和解析网络请求的数据包时。以下是对代码各个部分的详细解释#xff0c;帮助您更好地理解这些代码的作用。
代码概述
这段代码主要负责从网络读取数据包#xff0c;它包含了多个函数来处理网络数据的读取、缓…MySQL 8 版本中的客户端-服务器通信相关特别是在接收和解析网络请求的数据包时。以下是对代码各个部分的详细解释帮助您更好地理解这些代码的作用。
代码概述
这段代码主要负责从网络读取数据包它包含了多个函数来处理网络数据的读取、缓冲区管理、包的解压缩、重试机制和超时处理等。
核心部分概述 net_read_packet 函数 该函数是 MySQL 网络协议栈的一个核心函数用于从网络上读取一个数据包。它处理了数据包头的读取、压缩包的处理、包的重新分配和数据的实际读取。其工作流程是 读取包头获取包的长度。如果包是压缩的则解压缩并更新 complen解压后的包长度。检查是否需要扩展缓冲区来适应包的内容。最终调用 net_read_raw_loop 读取实际的包数据。 net_read_raw_loop 函数 这个函数是读取原始数据的实际工作函数它通过 vio_read 函数从套接字中读取指定数量的字节。如果读取过程中遇到错误会进行重试如果读取到 EOF 或者发生超时它会处理这些情况并返回相应的错误。 net_read_uncompressed_packet 函数 该函数处理未压缩的数据包读取数据包并检查是否是一个大数据包的开始。如果数据包是一个多包数据的开始通过 0xFFFFFF 标识则会继续读取后续的包并将它们连接在一起。 my_net_read 函数 这是一个统一的入口函数用于读取数据包。根据网络连接的压缩标志它会选择读取压缩或未压缩的包。如果是压缩包它会调用 net_read_compressed_packet否则调用 net_read_uncompressed_packet。 Protocol_classic::read_packet 函数 这个函数属于 MySQL 8 协议类 Protocol_classic 的一部分。它调用 my_net_read 来读取数据包并检查数据包的有效性。如果数据包的长度无效packet_error则标记该包为错误包。否则它将数据包存储在 input_raw_packet 中并返回成功。 Protocol_classic::get_command 函数 这个函数解析并处理客户端发送的命令数据包。它首先调用 read_packet 函数读取数据包然后从数据包的第一个字节中提取命令类型如 COM_SLEEP 等并将其存储到 cmd 变量中。接着它会跳过命令字节并解析剩余的数据。
数据包读取过程 数据包头读取net_read_packet 首先通过 net_read_packet_header 函数读取数据包的头部信息包括数据包的长度。如果数据包头部的读取失败它会返回错误。 压缩数据包的处理如果数据包是压缩的net-compress 为真则会通过 net_read_compressed_packet 解压缩数据包并更新 complen解压后的数据包长度。压缩包的具体处理逻辑是通过解析压缩包的头部和数据内容来完成的。 多包处理如果数据包的长度为最大值MAX_PACKET_LENGTH则表示这是一个多包数据的第一部分需要继续读取后续的包并将它们拼接在一起。这个过程在 net_read_uncompressed_packet 函数中进行。 错误处理和超时机制如果在读取过程中发生错误net_read_raw_loop 会处理多种情况如重试、EOF 或超时。错误信息通过 net-last_errno 进行记录客户端会根据这个信息做相应的处理。特别地超时会触发不同的错误如 ER_NET_READ_INTERRUPTED 或 ER_CLIENT_INTERACTION_TIMEOUT。
关键函数总结
net_read_packet负责读取一个完整的网络数据包处理压缩和扩展缓冲区的逻辑。net_read_raw_loop核心的循环读取函数负责从网络读取数据并处理错误和超时。my_net_read统一的接口函数调用 net_read_compressed_packet 或 net_read_uncompressed_packet 来读取数据包。Protocol_classic::read_packet 和 Protocol_classic::get_command这两个函数属于 MySQL 协议类负责接收客户端请求并解析相应的命令。
结论
这些代码主要用于处理 MySQL 8 客户端和服务器之间的网络通信特别是处理数据包的读取、解压、分片拼接以及错误处理。它们确保能够从客户端接收到数据包并将其解析为 MySQL 服务器理解的格式。这些代码对于处理客户端请求、执行 SQL 命令和返回结果至关重要。
##源码
static size_t net_read_packet(NET *net, size_t *complen) {size_t pkt_len, pkt_data_len;*complen 0;net-reading_or_writing 1;/*We should reset compress_packet_nr even before reading the header becausereading can fail and then the compressed packet number wont get reset.*/net-compress_pkt_nr net-pkt_nr;/* Retrieve packet length and number. */if (net_read_packet_header(net)) goto error;net-compress_pkt_nr net-pkt_nr;if (net-compress) {/*The right-hand expressionmust match the size of the buffer allocated in net_realloc().*/assert(net-where_b NET_HEADER_SIZE 3 net-max_packet NET_HEADER_SIZE COMP_HEADER_SIZE);/*If the packet is compressed then complen 0 and contains thenumber of bytes in the uncompressed packet.*/*complen uint3korr((net-buff[net-where_b NET_HEADER_SIZE]));}/* The length of the packet that follows. */pkt_len uint3korr(net-buff net-where_b);/* End of big multi-packet. */if (!pkt_len) goto end;pkt_data_len max(pkt_len, *complen) net-where_b;/* Expand packet buffer if necessary. */if ((pkt_data_len net-max_packet) net_realloc(net, pkt_data_len))goto error;/* Read the packet data (payload). */if (net_read_raw_loop(net, pkt_len)) goto error;end:if (net-error NET_ERROR_SOCKET_NOT_WRITABLE)net-error NET_ERROR_SOCKET_UNUSABLE;DBUG_DUMP(net read, net-buff net-where_b, pkt_len);net-reading_or_writing 0;return pkt_len;error:if (net-error NET_ERROR_SOCKET_NOT_WRITABLE)net-error NET_ERROR_SOCKET_UNUSABLE;net-reading_or_writing 0;return packet_error;
}/*****************************************************************************
** Read something from server/clinet
*****************************************************************************//**Read a determined number of bytes from a network handler.param net NET handler.param count The number of bytes to read.return true on error, false on success.
*/static bool net_read_raw_loop(NET *net, size_t count) {DBUG_TRACE;bool eof false;unsigned int retry_count 0;uchar *buf net-buff net-where_b;bool timeout_on_full_packet false;bool is_packet_timeout false;
#ifdef MYSQL_SERVERNET_SERVER *server_ext static_castNET_SERVER *(net-extension);if (server_ext) timeout_on_full_packet server_ext-timeout_on_full_packet;
#endiftime_t start_time 0;if (timeout_on_full_packet) start_time time(start_time);while (count) {const size_t recvcnt vio_read(net-vio, buf, count);/* VIO_SOCKET_ERROR (-1) indicates an error. */if (recvcnt VIO_SOCKET_ERROR) {/* A recoverable I/O error occurred? */if (net_should_retry(net, retry_count))continue;elsebreak;}/* Zero indicates end of file. */else if (!recvcnt) {eof true;break;}count - recvcnt;buf recvcnt;
#ifdef MYSQL_SERVERthd_increment_bytes_received(recvcnt);
#endifif (timeout_on_full_packet) {time_t current_time time(current_time);if (static_castunsigned int(current_time - start_time) net-read_timeout) {is_packet_timeout true;break;}}}/* On failure, propagate the error code. */if (count) {/* Interrupted by a timeout? */if (!eof (vio_was_timeout(net-vio) || is_packet_timeout))net-last_errno ER_NET_READ_INTERRUPTED;elsenet-last_errno ER_NET_READ_ERROR;#ifdef MYSQL_SERVER/* First packet always wait for net_wait_timeout */if (net-pkt_nr 0 (vio_was_timeout(net-vio) || is_packet_timeout)) {net-last_errno ER_CLIENT_INTERACTION_TIMEOUT;/* Socket should be closed after trying to write/send error. */THD *thd current_thd;if (thd) {Security_context *sctx thd-security_context();std::string timeout{std::to_string(thd_get_net_wait_timeout(thd))};Auth_id auth_id(sctx-priv_user(), sctx-priv_host());LogErr(INFORMATION_LEVEL, ER_NET_WAIT_ERROR2, timeout.c_str(),auth_id.auth_str().c_str());} else {LogErr(INFORMATION_LEVEL, ER_NET_WAIT_ERROR);}}net-error NET_ERROR_SOCKET_NOT_READABLE;/*Attempt to send error message to client although the client wont beexpecting messages. If later the client tries to send a command and failit will instead check if it can read an error message.*/my_error(net-last_errno, MYF(0));
#else/* Socket should be closed. */net-error NET_ERROR_SOCKET_UNUSABLE;
#endif}return count ! 0;
}/**Reads one packet to net-buff net-where_b.If the packet is the first packet of a multi-packet packet(which is indicated by the length of the packet 0xffffff) thenall sub packets are read and concatenated.param[in, out] net NET structureparam[out] len length of the packet read
*/
static void net_read_uncompressed_packet(NET *net, size_t len) {size_t complen;assert(!net-compress);len net_read_packet(net, complen);if (len MAX_PACKET_LENGTH) {/* First packet of a multi-packet. Concatenate the packets */const ulong save_pos net-where_b;size_t total_length 0;do {net-where_b len;total_length len;len net_read_packet(net, complen);} while (len MAX_PACKET_LENGTH);if (len ! packet_error) len total_length;net-where_b save_pos;}net-read_pos net-buff net-where_b;if (len ! packet_error)net-read_pos[len] 0; /* Safeguard for mysql_use_result */
}/**Read a packet from the client/server and return it without the internalpackage header.If the packet is the first packet of a multi-packet packet(which is indicated by the length of the packet 0xffffff) thenall sub packets are read and concatenated.If the packet was compressed, its uncompressed and the length of theuncompressed packet is returned.returnThe function returns the length of the found packet or packet_error.net-read_pos points to the read data.
*/ulong my_net_read(NET *net) {size_t len;/* turn off non blocking operations */if (!vio_is_blocking(net-vio)) vio_set_blocking_flag(net-vio, true);if (net-compress)net_read_compressed_packet(net, len);elsenet_read_uncompressed_packet(net, len);return static_castulong(len);
}int Protocol_classic::read_packet() {input_packet_length my_net_read(m_thd-net);if (input_packet_length ! packet_error) {assert(!m_thd-net.error);bad_packet false;input_raw_packet m_thd-net.read_pos;return 0;}bad_packet true;return m_thd-net.error NET_ERROR_SOCKET_UNUSABLE ? 1 : -1;
}int Protocol_classic::get_command(COM_DATA *com_data,enum_server_command *cmd) {// read packet from the networkif (const int rc read_packet()) return rc;/*input_packet_length contains length of data, as it was stored in packetheader. In case of malformed header, my_net_read returns zero.If input_packet_length is not zero, my_net_read ensures that the returnednumber of bytes was actually read from network.There is also an extra safety measure in my_net_read:it sets packet[input_packet_length] 0, but only for non-zero packets.*/if (input_packet_length 0) /* safety */{/* Initialize with COM_SLEEP packet */input_raw_packet[0] (uchar)COM_SLEEP;input_packet_length 1;}/* Do not rely on my_net_read, extra safety against programming errors. */input_raw_packet[input_packet_length] \0; /* safety */*cmd (enum enum_server_command)(uchar)input_raw_packet[0];if (*cmd COM_END) *cmd COM_END; // Wrong commandassert(input_packet_length);// Skip commandinput_packet_length--;input_raw_packet;return parse_packet(com_data, *cmd);
}
##gdb调试栈
(gdb) bt
#0 net_read_packet (net0x7fd000002bb8, complen0x7fd0e48fc250) at /home/yym/mysql8/mysql-8.1.0/sql-common/net_serv.cc:2125
#1 0x00005d830c9eb995 in net_read_uncompressed_packet (net0x7fd000002bb8, len0x7fd0e48fc290: 140535164556864) at /home/yym/mysql8/mysql-8.1.0/sql-common/net_serv.cc:2165
#2 0x00005d830c9ebccc in my_net_read (net0x7fd000002bb8) at /home/yym/mysql8/mysql-8.1.0/sql-common/net_serv.cc:2241
#3 0x00005d830cf1cd2a in Protocol_classic::read_packet (this0x7fd0000052e0) at /home/yym/mysql8/mysql-8.1.0/sql/protocol_classic.cc:1411
#4 0x00005d830cf1e08f in Protocol_classic::get_command (this0x7fd0000052e0, com_data0x7fd0e48fc340, cmd0x7fd0e48fc330)at /home/yym/mysql8/mysql-8.1.0/sql/protocol_classic.cc:2995
#5 0x00005d830c7c0b5a in do_command (thd0x7fd000000d80) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1397
#6 0x00005d830ca18835 in handle_connection (arg0x5d83166b17d0) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303
#7 0x00005d830e957bdc in pfs_spawn_thread (arg0x5d83166ae7e0) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043
#8 0x00007fd0f3894ac3 in start_thread (argoptimized out) at ./nptl/pthread_create.c:442
#9 0x00007fd0f3926850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
(gdb) p net-buff
$10 (unsigned char *) 0x7fd0000076f0 \003KILL QUERY 8