背景
最近工作中有个项目,用 Phalcon 框架开发,涉及 RabbitMQ,所以自己写了个类来处理消息。
部署时用 Supervisor 监管,但发现一段时间没有业务触发就会出现 SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
的错误。
分析
为什么会出现这个错误?官方给出了解释 https://dev.mysql.com/doc/refman/5.7/en/gone-away.html
The most common reason for the MySQL server has gone away error is that the server timed out and closed the connection.
In this case, you normally get one of the following error codes (which one you get is operating system-dependent).
也就是说,出现 gone away,大部分是因为服务超时或断连了,而且错误码不一定是 2006(CR_SERVER_GONE_ERROR),也可能是 2013(CR_SERVER_LOST)。
常见的原因大致有:
- 运行线程被杀掉了。
- 关闭连接后又发出了SQL查询。
- 运行环境没有授权连接MySQL。
- 客户端的TCP/IP连接超时。
比如做了这样的设置mysql_options(..., MYSQL_OPT_READ_TIMEOUT,...)
或mysql_options(..., MYSQL_OPT_WRITE_TIMEOUT,...)
。 - wait_timeout,即,服务端主动关闭超时未交互的连接。
- 异常查询请求导致服务端主动关闭连接。
比如 超出了max_allowed_packet
变量设定的查询限制。
所以,大概率是 wait_timeout
导致的。
解决
用 show variables like '%timeout%';
查看 MySQL 的 wait_timeout
和 interactive_timeout
。
如果 my.ini 中没有配置,则默认 wait_timeout
为 28800,即,8小时。
为了测试,修改本地 MySQL 的 my.ini 配置:
1 | [mysqld] |
直接上代码(一段实现异常重连的示例代码):