一尘不染

MySQL读取通讯包报错

mysql

在 MySQL 错误日志中,我看到了一些类似这样的警告:

120611 16:12:30 [Warning] Aborted connection 2619503 to db: 'db_name' user: 'user_name' host: 'webapp_hostname' (Got an error reading communication packets)

没有注意到任何数据本身的丢失,所以我想知道这个警告是什么意思,或者是什么原因造成的,以及是否可以解决导致这些问题的问题。这是在 RHEL 6.1 和 MySQL Enterprise 5.5 上。


阅读 101

收藏
2022-10-21

共1个答案

一尘不染

MySQL 连接的沉默杀手之一是 MySQL 数据包。

首先,让我们弄清楚 MySQL Packet 是什么。

根据”Understanding MySQL Internals” (ISBN 0-596-00957-7) 的第 99 页,这里是解释 MySQL 数据包的第 1-3 段:

MySQL 网络通信代码是在查询总是相当短的假设下编写的,因此可以以一个块的形式发送到服务器并由服务器处理,在 MySQL 术语中称为数据包。服务器为临时缓冲区分配内存来存储数据包,并请求足够的内存以完全容纳它。这种架构需要采取预防措施来避免服务器内存不足——这个选项可以实现数据包大小的上限。

与此选项相关的代码可在 sql/net_serv.cc中找到。查看my_net_read(),然后按照对my_real_read()的调用并特别注意 net_realloc()

此变量还限制了许多字符串函数的结果的长度。有关详细信息,请参阅sql/field.ccsql/intem_strfunc.cc

了解有关 MySQL 数据包的这一点后,开发人员/DBA 可以调整它们的大小以在一个数据包中容纳多个 BLOB,即使它们大得令人讨厌。当然,一个太小的数据包会在这方面导致打开连接的问题。

根据MySQL 文档

  • 如果您向服务器发送不正确或太大的查询,您也可能会收到这些错误。如果 mysqld 收到一个太大或乱序的数据包,它会假定客户端出现问题并关闭连接。如果您需要大查询(例如,如果您使用大 BLOB 列),您可以通过设置服务器的 max_allowed_packet 变量来增加查询限制,该变量的默认值为 1MB。您可能还需要增加客户端的最大数据包大小。有关设置数据包大小的更多信息,请参见第 C.5.2.10 节,“数据包太大”。
  • 插入大量行的 INSERT 或 REPLACE 语句也可能导致这类错误。无论要插入的行数如何,这些语句中的任何一个都向服务器发送单个请求;因此,您通常可以通过减少每次 INSERT 或 REPLACE 发送的行数来避免错误。

推荐

尝试将max_allowed_packet提高到更大的数字,因为默认值为 1M。我建议您在当前数据集中拥有的最大 TEXT 或 BLOB 字段大约是 10 倍。

要将 max_allowed_packet 设置为 256M,可以将其添加到 /etc/my.cnf 或 my.ini

[mysqld]
max_allowed_packet=256M

以涵盖 mysqld 的未来重新启动。要立即在服务器上安装该值,请运行以下命令:

SET GLOBAL max_allowed_packet = 1024 * 1024 * 256;

试试看 !!!

2022-10-21