前几天在群里有个朋友问到max_allowed_packet被自动重置的问题,于是打算写个文章来描述下,因为遇到这个问题的人不少,但是提到的解决方案几乎没有。

max_allowed_packet指的是服务器接收的包的大小,该值设置过小,可能导致数据写入失败,通常可以通过修改my.cnf或者在命令行通过set max_allowed_packet来实现。

但是在实际情况中,我们很多时候会遇到这样的一种情况:通过各种方式设置了max_allowed_packet的值,但是一段时间后,max_allowed_packet还是莫名其妙的变成了1024,而my.cnf里面的值还是之前设置的大于1024的值。

这个问题看起来很诡异,但是至少可以确定一点,那就是该值通过某某连接,在连接里面通过set命令给重置了。

一般来说,引起该问题不外乎如下几种情况:

设置不当:设置该值需要修改my.cnf配置,但是一共需要设置两处,如下:

max_allowed_packet=10240

max_allowed_packet=10240

mysqld里面控制的是服务端,mysql里面控制的是客户端,如果只设置一处,则当有客户端连接的时候,该值会被重置。

内存不足:当mysql执行大批次查询语句大时候,因为服务器内存不足,引起预警,mysql会重置这个值,已保证数据库的稳定。

黑客攻击:其实在生产环境下,大多数的情况,还真是被攻击了,针对这个情况,需要集中查看,安全不容小觑,mysql 有general_log, 会记录所有执行的sql命令,因为耗费性能,默认是关闭。

mysql> show variables like '%log%';

+-----------------------------------------+---------------------------------+

| Variable_name                           | Value                           |

+-----------------------------------------+---------------------------------+

| back_log                                | 50                              |

| binlog_cache_size                       | 32768                           |

| binlog_direct_non_transactional_updates | OFF                             |

| binlog_format                           | STATEMENT                       |

| expire_logs_days                        | 0                               |

| general_log                             | OFF                             |

| general_log_file                        | /var/run/mysqld/mysqld.log      |

打开general_log:

mysql> set global general_log = ON;

查看general_log:

tail -f /var/run/mysqld/mysqld.log |grep max_allowed_packet (查看log,但打印大量实时sql操作)

tail -f /var/run/mysqld/mysqld.log |grep max_allowed_packet >1.txt (过滤max_allowed_packet,并输出到文件1.txt)

通过日志查看修改的对应的ip地址,然后通过设置黑名单或者修改数据库密码来解决。

总结:生产环境下,应该绝对避免使用root作为数据库连接用户,另外对授权需要严格控制,尽量不要分配给应用的账户修改配置的权限,这样可以避免这类情况的发生,同时提升服务器的安全性。