解决LostconnectiontoMySQLserverduringquery错误⽅法
昨天使⽤Navicat for MySQL导⼊MySQL数据库的时候,出现了⼀个严重的错误,Lost connection to MySQL server during query,字⾯意思就是在查询过程中丢失连接到MySQL服务器。
[Msg]
[Msg] Table Created: wp_wiki_copy
[Msg]
[Msg] 2013 - Lost connection to MySQL server during query
[Msg] Table Restored: wp_wiki_copy
[Msg] Finished - Stopped before completion
我的数据量⼤概了5万条,备份的数据库⽂件⼤⼩有240M,这还是压缩了的,确实有点⼤。初步判断是MySQL可能挂掉了,在系统服务⾥⾯查看MySQL的进程并没有停⽌。最开始考虑是数据库结构不对,但是我是通过Navicat for MySQL的备份和恢复备份导⼊数据,应该表结构都在备份⽂件⾥⾯,应该不是
数据库结构的问题。⽹络环境都是本地。也不可能是⽹络链接和数据库服务器的问题。最后在早上到了解决⽅法,在my.ini配置⽂件 mysqld 节点下添加
max_allowed_packet = 500M
配置MySQL允许的最⼤数据包⼤⼩,上⾯的500000M你可以根据你的项⽬修改为你⾃⼰的值,只要⽐要导⼊的备份⽂件⼤就可以了。
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下载链接
即某个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。⼤概浏览了⼀下,主要可能是因为以下⼏种原因:
max_allowed_packet的⼤⼩,如果是这种原因,你只要修改myf,加
⼀种可能是发送的SQL语句太长,以致超过了max_allowed_packet
max_allowed_packet的值即可。
⼤max_allowed_packe
可能是某些原因导致超时,⽐如程序中获取数据库连接时采⽤Singleton做法,虽然多次连接数据库,但其实使⽤的都是同⼀个连接,⽽且程序中
wait_timeout(SHOW STATUS能看到此设置),那么就可能出现问题。最简单的处理⽅式就是把
某两次操作数据库的间隔时间超过了wait_timeout
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”这样的错误提⽰,解决这个问题,我的经验有以下两点,或许对⼤家有⽤处:
第 ⼀种⽅法:
myf(在Windows下台下⾯是my.ini)中设置,我的数据库负荷当然是增加你的 wait-timeout值
wait-timeout值,这个参数是在myf(在Windows下台下⾯是my.ini)稍微⼤⼀点,所以,我设置的值 为10,(这个值的单位是秒,意思是当⼀个数据库连接在10秒钟内没有任何操作的话,
mysql_connect,关于这个wait-timeout的效果
mysql_pconnect),⽤的是mysql_connect
就会强⾏关闭,我使⽤的不是永久链接 (mysql_pconnect
你可以在MySQL的进程列表中看到 (show processlist) ),你可以把这个wait-timeout设置成更⼤,⽐如300秒,呵
,其实你也可以不⽤设置,MySQL默认是8个⼩ 时。情况由你的服务器和站点来呵,⼀般来讲300秒⾜够⽤了,其实你也可以不⽤设置,MySQL默认是8个⼩ 时。情况由你的服务器和站点来定。
第⼆种⽅法:
这也是我个⼈认为最好的⽅法,即检查 MySQL的链接状态,使其重新链接。
mysql_ping的 API会检查数据库是否链接,如果是断开的话会尝试重新mysql_ping这么⼀个函数,在很多资料中都说这个mysql_ping
可能⼤家都知道有mysql_ping
连接,但在我的测试过程中发现事实并不是这样⼦的,是有条件的,必须要通过 mysql_options这个C API传递相关参数,让MYSQL有断开⾃动链接的选项(MySQL默认为不⾃动连接),但我测试中发现PHP的MySQL的API中并不带这个函数,你重新编辑MySQL吧,但mysql_ping这个函数还是终于能⽤得上的,只是要在其中有⼀个⼩⼩的操作技巧:
我需要调⽤这个函数的代码可能是这样⼦的
$str = file_get_contents('www.jb51');
$db->ping();//经过前⾯的⽹页抓取后,或者会导致数据库连接关闭,检查并重新连接
$db->query('select * from table');
ping()这个函数先检测数据连接是否正常,如果被关闭,整个把当前脚本的MYSQL实例关闭,再重新连接。
经 过这样处理后,可以⾮常有效的解决MySQL server has gone away这样的问题,⽽且不会对系统造成额外的开销。
1) ⽅法1
可以编辑myf来修改(windows下my.ini),在[mysqld]段或者mysql的server配置段进⾏修改。
max_allowed_packet = 20M
如果不到myf可以通过
mysql --help | grep myf
去寻myf⽂件。
2) ⽅法2
(很妥协,很纠结的办法)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。