vlambda博客
学习文章列表

mysql-请求包大小限制

问题

今天在开发环境测试即将要上线的一个功能,其中有一个步骤会往 mysql 数据库批量插入大量数据。在测试的过程发现流程失败了,查看日志发现了这么一个错误。

### Error updating database.  Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (6034195 > 4194304). You can change this value on the server by setting the max_allowed_packet' variable.

包大小限制

在经过一番探索之后,发现原来是请求 mysql 服务的时候,请求的包超出了 mysql 服务的限制,因此被拒绝了。

在 mysql 数据库会话中,client 通过向 mysql server 发送数据包请求,也就是我们程序中涉及的 sql,server 接受到请求之后,执行 sql,返回结果。

参考 官方文档:

When a MySQL client or the mysqld server receives a packet bigger than max_allowed_packet bytes, it issues an ER_NET_PACKET_TOO_LARGE error and closes the connection. With some clients, you may also get a Lost connection to MySQL server during query error if the communication packet is too large.

mysql 会通过一个  max_allowed_packet  变量来设置允许接收的最大请求包大小(单位 byte), 如果超出限制,则会关闭连接。在 mysql client 中可以查看当前 max_allowed_packet 设置的限制值。

show VARIABLES like '%max_allowed_packet%';

解决方法

修改配置

可以调整 mysql 服务端配置的 max_allowed_packet 值。

配置文件

找到 mysql 的配置文件(linux 一般在 /etc/my.cnf),一不做二不休,修改 server 端关于 max_allowed_packet 的配置值

shell 命令

在 mysql client 中执行命令

set global max_allowed_packet = 16M;

想通过这个方法修改公司开发环境 mysql 服务的配置,发现需要超级管理员权限。

程序优化

修改配置的方法存在很大的问题:

  • 修改成什么值合适呢?未来有更大的包发送,是不是又需要改这个配置

  • 很多情况下我们是无法修改这个配置

另外 mysql 设置这个限制也有它的用途,防止客户端程序发送大小不合理的请求,也警示程序应该进行相关优化了,超大请求也许会导致服务处理时间过程,对其它客户端造成影响。

另外我问了公司的 DBA 这个字段是出于什么考虑,提到了『大事务』这个词,对 mysql 服务是非常不友好的,关于大事务带来的问题,可以参照这篇文章 MYSQL大表与大事务带来的问题

mysql-请求包大小限制

优化思路其实很简单,不让我们一次性发这么多,那我们就分批发呗,将大请求拆分成一个个更小的请求,所以我们团队里形成了一些规定,比如数据导入导出涉及的数据量太大,需要考虑做成分批请求。



大家的关注是我持续输出的动力

长按扫码可关注