MySQLserverhasgoneaway问题的解决⽅法
mysql出现ERROR : (2006, 'MySQL server has gone away') 的问题意思就是指client和MySQL server之间的链接断开了。
造成这样的原因⼀般是sql操作的时间过长,或者是传送的数据太⼤(例如使⽤insert ... values的语句过长,这种情况可以通过修改max_allowed_packed的配置参数来避免,也可以在程序中将数据分批插⼊)。
产⽣这个问题的原因有很多,总结下⽹上的分析:
原因⼀. MySQL 服务宕了
判断是否属于这个原因的⽅法很简单,进⼊mysql控制台,查看mysql的运⾏时长
mysql> show global status like 'uptime';
+---------------+---------+
| Variable_name | Value |
+---------------+---------+
| Uptime | 3414707 |
+---------------+---------+
1 row in set或者查看MySQL的报错⽇志,看看有没有重启的信息
如果uptime数值很⼤,表明mysql服务运⾏了很久了。说明最近服务没有重启过。
如果⽇志没有相关信息,也表名mysql服务最近没有重启过,可以继续检查下⾯⼏项内容。
原因⼆. mysql连接超时
即某个mysql长连接很久没有新的请求发起,达到了server端的timeout,被server强⾏关闭。
此后再通过这个connection发起查询的时候,就会报错server has gone away
(⼤部分PHP脚本就是属于此类)
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
wait_timeout 是28800秒,即mysql链接在⽆操作28800秒后被⾃动关闭
原因三. mysql请求链接进程被主动kill
这种情况和原因⼆相似,只是⼀个是⼈为⼀个是MYSQL⾃⼰的动作
mysql> show global status like 'com_kill';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_kill | 21 |
+---------------+-------+
1 row in set原因四. 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 | 1048576 |
+--------------------+---------+
1 row in set (0.00 sec)
修改参数:
mysql> set global max_allowed_packet=1024*1024*16;
mysql> show global variables like 'max_allowed_packet';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| max_allowed_packet | 16777216 |
+--------------------+----------+
1 row in set (0.00 sec)
以下是补充:
应⽤程序(⽐如PHP)长时间的执⾏批量的MYSQL语句。执⾏⼀个SQL,但SQL语句过⼤或者语句中含有BLOB或者longblob字段。⽐如,图⽚数据的处理。都容易引起MySQL server has gone away。
mysql下载链接今天遇到类似的情景,MySQL只是冷冷的说:MySQL server has gone away。
⼤概浏览了⼀下,主要可能是因为以下⼏种原因:
⼀种可能是发送的SQL语句太长,以致超过了max_allowed_packet的⼤⼩,如果是这种原因,你只要修改myf,加⼤max_allowed_packet的值即可。
还有⼀种可能是因为某些原因导致超时,⽐如说程序中获取数据库连接时采⽤了Singleton的做法,虽然多次连接数据库,但其实使⽤的都是同⼀个连接,⽽且程序中某两次操作数据库的间隔时间超过了wait_timeout(SHOW STATUS能看到此设置),那么就可能出现问题。最简单的处理⽅式就是把wait_timeout改⼤,当然你也可以在程序⾥时不时顺⼿mysql_ping()⼀下,这样MySQL就知道它不是⼀个⼈在战⽃。
解决MySQL server has gone away
1、应⽤程序(⽐如PHP)长时间的执⾏批量的MYSQL语句。最常见的就是采集或者新旧数据转化。
解决⽅案:
在myf⽂件中添加或者修改以下两个变量:
wait_timeout=2880000
interactive_timeout = 2880000
关于两个变量的具体说明可以google或者看官⽅⼿册。如果不能修改myf,则可以在连接数据库的时候设置
CLIENT_INTERACTIVE,⽐如:
sql = "set interactive_timeout=24*3600";
mysql_real_query(...)
2、执⾏⼀个SQL,但SQL语句过⼤或者语句中含有BLOB或者longblob字段。⽐如,图⽚数据的处理
解决⽅案:
在myf⽂件中添加或者修改以下变量:
max_allowed_packet = 10M(也可以设置⾃⼰需要的⼤⼩)
max_allowed_packet 参数的作⽤是,⽤来控制其通信缓冲区的最⼤长度。
最近做⽹站有⼀个站要⽤到WEB⽹页采集器功能,当⼀个PHP脚本在请求URL的时候,可能这个被请求的⽹页⾮常慢慢,超过了mysql的 wait-timeout时间,然后当⽹页内容被抓回来后,准备插⼊到MySQL的时候,发现MySQL的连接超时关闭了,于是就出现了“MySQL server has gone away”这样的错误提⽰,解决这个问题,我的经验有以下两点,或许对⼤家有⽤处:
第⼀种⽅法:
当然是增加你的 wait-timeout值,这个参数是在myf(在Windows下台下⾯是my.ini)中设置,我的数据库负荷稍微⼤⼀点,所以,我设置的值为10,(这个值的单位是秒,意思是当⼀个数据库连接在10秒钟内没有任何操作的话,就会强⾏关闭,我使⽤的不是永久链接(mysql_pconnect),⽤的是mysql_connect,关于这个wait-timeout的效果你可以在MySQL的进程列表中看到(show processlist) ),你可以把这个wait-timeout设置成更⼤,⽐如300秒,呵呵,⼀般来讲300秒⾜够⽤了,其实你也可以不⽤设置,MySQL默认是8个⼩时。情况由你的服务器和站点来定。
第⼆种⽅法:
这也是我个⼈认为最好的⽅法,即检查 MySQL的链接状态,使其重新链接。
可能⼤家都知道有mysql_ping这么⼀个函数,在很多资料中都说这个mysql_ping的 API会检查数据库是否链接,如果是断开的话会尝试重新连接,但在我的测试过程中发现事实并不是这样⼦的,是有条件的,必须要通过 mysql_options这个C API传递相关参数,让MYSQL有断开⾃动链接的选项(MySQL默认为不⾃动连接),但我测试中发现PHP的MySQL的API中并不带这个函数,你重新编辑MySQL吧,呵呵。但mysql_ping这个函数还是终于能⽤得上的,只是要在其中有⼀个⼩⼩的操作技巧:
这是我的的数据库操作类中间的⼀个函数
复制代码代码如下:
function ping(){
if(!mysql_ping($this->link)){
mysql_close($this->link); //注意:⼀定要先执⾏数据库关闭,这是关键
$this->connect();
}
}
我需要调⽤这个函数的代码可能是这样⼦的
复制代码代码如下:
$str = file_get_contents('//www.jb51');
$db->ping();//经过前⾯的⽹页抓取后,或者会导致数据库连接关闭,检查并重新连接
$db->query('select * from table');
ping()这个函数先检测数据连接是否正常,如果被关闭,整个把当前脚本的MYSQL实例关闭,再重新连接。
经过这样处理后,可以⾮常有效的解决MySQL server has gone away这样的问题,⽽且不会对系统造成额外的开销。
今天遇到类似的情景,MySQL只是冷冷的说:MySQL server has gone away。
⼤概浏览了⼀下,主要可能是因为以下⼏种原因:
⼀种可能是发送的SQL语句太长,以致超过了max_allowed_packet的⼤⼩,如果是这种原因,你只要修改myf,加⼤max_allowed_packet的值即可。
还有⼀种可能是因为某些原因导致超时,⽐如说程序中获取数据库连接时采⽤了Singleton的做法,虽然多次连接数据库,但其实使⽤的都是同⼀个连接,⽽且程序中某两次操作数据库的间隔时间超过了wait_timeout(SHOW STATUS能看到此设置),那么就可能出现问题。最简单的处理⽅式就是把wait_timeout改⼤,当然你也可以在程序⾥时不时顺⼿
mysql_ping()⼀下,这样MySQL就知道它不是⼀个⼈在战⽃。
解决MySQL server has gone away
1、应⽤程序(⽐如PHP)长时间的执⾏批量的MYSQL语句。最常见的就是采集或者新旧数据转化。
解决⽅案:
在myf⽂件中添加或者修改以下两个变量:
wait_timeout=2880000
interactive_timeout = 2880000 关于两个变量的具体说明可以google或者看官⽅⼿册。如果不能修改myf,则可以在连接数据库的时候设置CLIENT_INTERACTIVE,⽐如:
sql = "set interactive_timeout=24*3600";
mysql_real_query(...)
2、执⾏⼀个SQL,但SQL语句过⼤或者语句中含有BLOB或者longblob字段。⽐如,图⽚数据的处理
解决⽅案:
在myf⽂件中添加或者修改以下变量:
max_allowed_packet = 10M(也可以设置⾃⼰需要的⼤⼩)
max_allowed_packet参数的作⽤是,⽤来控制其通信缓冲区的最⼤长度。
1、应⽤程序(⽐如PHP)长时间的执⾏批量的MYSQL语句。
最常见的就是采集或者新旧数据转化。
解决⽅案:
在my.ini⽂件中添加或者修改以下两个变量:
wait_timeout=2880000 interactive_timeout = 2880000
关于两个变量的具体说明可以google或者看官⽅⼿册。
如果不能修改myf,则可以在连接数据库的时候设置CLIENT_INTERACTIVE,⽐如:
sql = "set interactive_timeout=24*3600"; mysql_real_query(...)
2、执⾏⼀个SQL,但SQL语句过⼤或者语句中含有BLOB或者longblob字段。
⽐如,图⽚数据的处理
解决⽅案
在myf⽂件中添加或者修改以下变量:
max_allowed_packet = 10M (也可以设置⾃⼰需要的⼤⼩)
max_allowed_packet 参数的作⽤是,⽤来控制其通信缓冲区的最⼤长度。
修改⽅法
1)⽅法1
可以编辑myf来修改(windows下my.ini),在[mysqld]段或者mysql的server配置段进⾏修改。max_allowed_packet = 20M
如果不到myf可以通过
mysql --help | grep myf
去寻myf⽂件。
2)⽅法2
(很妥协,很纠结的办法)
进⼊mysql server
在mysql 命令⾏中运⾏
set global max_allowed_packet = 2*1024*1024*10
然后关闭掉这此mysql server链接,再进⼊。
show VARIABLES like '%max_allowed_packet%';
查看下max_allowed_packet是否编辑成功
------------以下是⽹络搜索的资料-------------------
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论