最近在安装完mysql之后发现error log 出现大量 Got an error reading communication packets 等的读写报错,如下图
问题分析
其实Aborted connection告警是很难避免的,error log里或多或少会有少量Aborted connection信息,这种情况是可以忽略的,但是当你的error log里频繁出现Aborted connection告警,这时候就应该注意了,可能会对业务产生较大的影响。
可能因素
A client attempts to access a database but has no privileges for
it.(没有权限)
A client uses an incorrect password.(密码错误)
A connection packet does not contain the right
information.(连接没有包含正确信息)
It takes more than connect_timeout seconds to obtain a connect
packet. (获取连接信息起过connect_timeout的时长)
The client program did not call mysql_close() before
exiting.(客户端没有调用mysql_close()函数)
The client had been sleeping more than wait_timeout or
interactive_timeout seconds without issuing any requests to the
server. (客户端的空连接时间过长,超过了wait_timeout和interactive_timeout的时间)
思路
Aborted_clients和Aborted_connects
请先查看这两个状态是否正常
mysql> show global status like '%abort%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| Aborted_clients | 32 |
| Aborted_connects | 45533 |
+------------------+-------+
2 rows in set (0.03 sec)
造成 Aborted_connects 状态变量增加的可能原因:
client端试图访问数据库,但没有数据库的权限。
client端使用了错误的密码。
client端连接包不包含正确的信息。
获取一个连接包需要的时间超过connect_timeout秒。
造成Aborted_clients状态变量增加的可能原因:
程序退出前,客户机程序没有调用mysql_close()。
客户端睡眠时间超过了wait_timeout或interactive_timeout参数的秒数。
客户端程序在数据传输过程中突然终止。
如果是正常的话,状态变量可能没有那么高
所以从下面几个方法开始解决吧
解决方法
max_allowed_packet
参数过小可能会导致操作异常,但是max_allowed_packet 最大值是1G(1073741824),如果设置超过1G,查看最终生效结果也只有1G
临时解决方案,修改该值
mysql> show variables like 'max_allowed_packet';
+--------------------+------------+
| Variable_name | Value |
+--------------------+------------+
| max_allowed_packet | 1073741824 |
+--------------------+------------+
1 row in set (0.04 sec)
set global max_allowed_packet = 10 * 1024 * 1024;
但是重启Mysql还是会恢复到默认值,所以需要写在配置文件当中
#永久性解决方案:
#修改方法1(配置文件持久化修改):
vim /etc/my.cnf
[mysqld]
max_allowed_packet = 100M
timeout
主要是wait_timeout, interactive_timeout 这两个参数值,MySQL连接时,服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。connections如果空闲超过8小时,Mysql将其断开,而DBCP连接池并不知道该connection已经失效,如果这时有Client请求connection,DBCP将该失效的Connection提供给Client,将会造成异常。
interactive_timeout 的黓认值为28800
wait_timeout 的默认值这:120
mysql> show global variables like '%timeout%';
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| have_statement_timeout | YES |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| rpl_stop_slave_timeout | 31536000 |
| slave_net_timeout | 60 |
| wait_timeout | 28800 |
+-----------------------------+----------+
13 rows in set (0.05 sec)
所以这个时间如果过小可能会导致异常,根据情况增加吧.这两个值是一个全局变量,可以动态增加,
set global interactive_timeout=28800;
timestamp
请查看你的数据库时间是否跟你的系统或者服务端同步
mysql> select current_timestamp() from dual;
+---------------------+
| current_timestamp() |
+---------------------+
| 2021-04-27 09:32:10 |
+---------------------+
1 row in set (0.00 sec)
如果不一样,那就在配置文件修改下吧,例如:
[mysqld]
max_allowed_packet=256M
default-time_zone = '+8:00'
log_warnings
#将log_warnings参数设为1
mysql> select @@log_warnings;
+----------------+
| @@log_warnings |
+----------------+
| 2 |
+----------------+
1 row in set
将log_warnings参数设为1
mysql> set global log_warnings=1;
Query OK, 0 rows affected
mysql> select @@log_warnings;
+----------------+
| @@log_warnings |
+----------------+
| 1 |
+----------------+
1 row in set
此时,上面的大量日志就不会出现在错误日志里面了。
官方对于log_warning的解释是这样的
英文原文
rint out warnings such as Aborted connection… to the error log. This option is enabled (1) by default. To disable it, use --log-warnings=0. Specifying the option without a level value increments the current value by 1. Enabling this option by setting it greater than 0 is recommended, for example, if you use replication (you get more information about what is happening, such as messages about network failures and reconnections). If the value is greater than 1, aborted connections are written to the error log, and access-denied errors for new connection attempts are written. See Section B.3.2.10, “Communication Errors and Aborted Connections”.
If a replica server was started with --log-warnings enabled, the
replica prints messages to the error log to provide information about
its status, such as the binary log and relay log coordinates where it
starts its job, when it is switching to another relay log, when it
reconnects after a disconnect, and so forth. The server logs messages
about statements that are unsafe for statement-based logging if
–log-warnings is greater than 0.
翻译一下
打印出警告,例如Aborted connection…错误日志。默认情况下启用此选项(1)。要禁用它,请使用 –log-warnings=0。指定不带level值的选项会将当前值增加1。建议通过将其设置为大于0来启用此选项,例如,如果您使用复制(您将获得有关正在发生的事情的更多信息,例如有关网络故障和重新连接的消息)。如果该值大于1,则将中止的连接写入错误日志,并写入新连接尝试的访问被拒绝的错误。请参见 第B.3.2.10节“通信错误和中止的连接”。
如果–log-warnings启用了副本服务器启动,则副本服务器
会将消息打印到错误日志中,以提供有关其状态的信息,例如二进制日志和中继日志坐标(在其开始工作时,切换到另一个中继日志时,何时开始)。断开连接后重新连接,依此类推。如果–log-warnings大于0
,服务器将记录有关对基于语句的日志记录不安全的语句的消息 。
你听懂了吗?反正我没听懂。还是我开头那句话:其实Aborted connection告警是很难避免的,error log里或多或少会有少量Aborted connection信息,这种情况是可以忽略的,但是当你的error log里频繁出现Aborted connection告警,这时候就应该注意了,可能会对业务产生较大的影响。
有的人会选择把–log-warnings设为0,这就是完全禁用了,但是没必要,我们过滤掉没必要的日志,等级设为1就可以了。
总结
以上四点就是我对Got an error reading communication packets的解决思路了,其实还有超时,没有权限,密码错误,连接配置错误等因素造成。