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 anER_NET_PACKET_TOO_LARGE
error and closes the connection. With some clients, you may also get aLost 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大表与大事务带来的问题
优化思路其实很简单,不让我们一次性发这么多,那我们就分批发呗,将大请求拆分成一个个更小的请求,所以我们团队里形成了一些规定,比如数据导入导出涉及的数据量太大,需要考虑做成分批请求。
长按扫码可关注