目录

目录 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) 只有收包的时候才知道包大小是否超过了。

 

02-01 20:10