目录
目录 1
1. 前言 1
2. 调用路径 2
3. MAX_PACKET_LENGTH宏 2
4. DBUG_RETURN宏 3
5. COM_QUERY枚举值 3
6. mysql_query函数 3
7. mysql_real_query函数 3
8. mysql_send_query函数 4
9. simple_command宏 5
10. MYSQL_METHODS结构体 5
11. cli_advanced_command函数 6
12. int3store函数 7
13. net_write_command函数 8
14. net_write_buff函数 10
15. net_write_packet函数 11
16. net_write_raw_loop函数 12
17. Vio结构体 13
18. vio_write函数 14
19. inline_mysql_socket_send函数 15
20. net_realloc函数 15
21. net_read_packet函数 16
22. mysql_real_connect函数 16
23. mysql_init函数 18
24. Packet Too Large 19
25. 分析结论 19
1. 前言
Review一同事的C++代码,发现其中有一个拼接而成的多记录INSERT语句可能超大(预计最大可超过1M,甚至10M也有可能,视实际记录条数而定)。担心包大存隐患,所以特意分析一下mysql_real_query函数的实现,以确保使用是否安全。研究对象为MySQL-8.0.14,其它版本可能有小许差异,但估计差异不会太大。
2. 调用路径
1) mysql_real_query调用路径
2) mysql_real_connect调用路径
3. MAX_PACKET_LENGTH宏
4. DBUG_RETURN宏
5. COM_QUERY枚举值
6. mysql_query函数
7. mysql_real_query函数
8. mysql_send_query函数
9. simple_command宏
10. MYSQL_METHODS结构体
11. cli_advanced_command函数
12. int3store函数
13. net_write_command函数
14. net_write_buff函数
15. net_write_packet函数
16. net_write_raw_loop函数
17. Vio结构体
18. vio_write函数
19. inline_mysql_socket_send函数
20. net_realloc函数
调用者:net_read_packet和my_realloc_str,net_realloc会对包大小进行判断,如果超过大小,设置出错码为ER_NET_PACKET_TOO_LARGE。
21. net_read_packet函数
22. mysql_real_connect函数
23. mysql_init函数
24. Packet Too Large
MySQL-8.0对“Packet Too Large”的官方说明:
25. 分析结论
1) 包的最大限制为1GB;
2) 如果包大小超过16M,则会被分解为多个子包,每个子包大小小于16M;
3) 分包是函数net_write_command的行为;
4) 即使被分解成了多个包,也并不立即发送;
5) 发送缓冲区满了才会立即发送;
6) 在函数net_read_packet中,调用net_realloc会判断包大小,如果超过大小,则错误码(last_errno)设置为ER_NET_PACKET_TOO_LARGE;
7) mysql_real_query并没有对要发送的大小进行判断,超过1G大小也是可以发的,但服务端会报错,这个由net_realloc决定,而调用者是;
8) 只有收包的时候才知道包大小是否超过了。