个人博客地址——https://www.dogebug.cn/
GitHub地址——https://github.com/yanshigou/
title: “MySQL server has gone away”
date: 2019-01-02 15:29
author: dzt
subtitle: 在查看celery.log时发现(2006, ‘MySQL server has gone away’)
tags:
- mysql
- study
前言
运行了很长时间的celery之后,发现有任务一直没有完成,也没有失败,一直处于执行当中,就去查看了celery的log。
截取了少部分error:
File "/home/ubuntu/www/cmxcelery/kkwork/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
self.errorhandler(self, exc, value)
File "/home/ubuntu/www/cmxcelery/kkwork/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
OperationalError: (2006, 'MySQL server has gone away')
怀疑是执行任务时间过长(一个任务大概会花4、5个小时),mysql连接时间过长,但并没有操作mysql(只会在开始和结束的时候进行mysql操作),导致client和MySQL server之间的链接断开了。
原因一、MySQL 服务宕了
判断是否属于这个原因的方法很简单,进入mysql控制台,查看mysql的运行时长
mysql> show global status like 'uptime'
-> ;
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| Uptime | 428464 |
+---------------+--------+
1 row in set (0.01 sec)
1 row in set或者查看MySQL的报错日志,看看有没有重启的信息
如果uptime数值很大,表明mysql服务运行了很久了。说明最近服务没有重启过。
如果日志没有相关信息,也表名mysql服务最近没有重启过,可以继续检查下面几项内容。
原因二、 mysql连接超时
即某个mysql长连接很久没有新的请求发起,达到了server端的timeout,被server强行关闭。
此后再通过这个connection发起查询的时候,就会报错server has gone away
mysql> show global variables like '%timeout';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| 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 |
| slave_net_timeout | 3600 |
| wait_timeout | 28800 |
+----------------------------+----------+
10 rows in set (0.01 sec)
wait_timeout 是28800秒,即mysql链接在无操作28800秒后被自动关闭
所以等待时间小于任务执行的时间,mysql被自动关闭了
解决方法:
1、立即生效
mysql> set global wait_timeout=60*60*24;
该命令是将wait_timeout设置为24小时。
用这种方法,修改完立即生效. 如果重启mysql,又恢复原来的28800秒。
2、永久生效
该方法修改完之后, 需要重启mysql才能生效.
编辑mysql配置文件my.cnf,添加或修改为下面这条命令.
(我的mysql配置文件路径: /etc/mysql/my.cnf )
[mysqld]
wait_timeout = 86400
interactive_timeout = 86400
当时在 /etc/mysql/my.cnf中修改的时候 没有加上 [mysqld]这个标志 导致语法错误 而不能启动mysql
还有网上别人遇到的错误是 修改了变量之后没有生效。
这个方面的原因大概就是:
my.cnf中 还有引用了两个地方的设置:
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
这两个文件里面的mysql.conf配置也会被引进来 ,导致my.cnf中的配置被这两个文件中的配置覆盖。
原因三、 mysql请求链接进程被主动kill
这种情况和原因二相似,只是一个是人为一个是MYSQL自己的动作
mysql> show global status like 'com_kill';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_kill | 1 |
+---------------+-------+
1 row in set (0.05 sec)
原因四、 Your SQL statement was too large.
当查询的结果集超过 max_allowed_packet 也会出现这样的报错。定位方法是打出相关报错的语句。
用select * into outfile 的方式导出到文件,查看文件大小是否超过 max_allowed_packet ,如果超过则需要调整参数,或者优化语句。
mysql> show global variables like 'max_allowed_packet';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| max_allowed_packet | 16777216 |
+--------------------+----------+
1 row in set (0.00 sec)
修改参数:
mysql> set global max_allowed_packet=1024*1024*16;
mysql> show global variables like 'max_allowed_packet';
最后的解决办法:
主动断开连接 再进行连接数据库操作
from django.db import connection
from time import sleep
connection.close()
sleep(10)
2019-01-04 22:17
个人博客地址——https://www.dogebug.cn/
GitHub地址——https://github.com/yanshigou/
禁止不留原创地址、署名的转载
本人保留所有法定权利。违者必究
探讨Celery长时间运行任务中遇到的MySQL连接超时问题,分析四种可能的原因,包括MySQL服务状态、连接超时设置、主动kill请求及查询结果过大,并提供相应的解决策略。
4793

被折叠的 条评论
为什么被折叠?



