`
丁林.tb
  • 浏览: 797058 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

关于一次导入数据提示的MySQL server has gone away

阅读更多

背景

这个问题由一个同事问到的一次导入数据引发。一个很常见的操作,将数据从一个表中dump出来,在用mysql < a.sql的方式导入到另一个库的一个表中。

在执行导入的时候,提示 MySQL server has gone away。在追查的时候突然想到会不会是因为max_allowed_packet太小导致的。将max_allowed_packet改大,确实解决了问题。

本文基于在此之后想到的两个问题:

1、  MySQL server has gone away这个提示很不友好,是不是所有的包超过大小都是报这个?

2、  对于出现这种不友好的错误提示,有什么方法定位原因(而不是靠“突然想到”)?

 

追查1

  步骤:a) 把max_allowed_packet设置为一个比较小的值, set global max_allowed_packet=16384

           b) 写一个简单的语句 insert into tb values(xxx),(xxx),(xxx)……(xxx) 让这个文件足够大,比如我测试使用 a.sql大小为37318

           c) 执行导入语句,提示 ER2ROR 1153 (08S01) at line 1: Got a packet bigger than ‘max_allowed_packet’ bytes

 

    初步结论是并不是所有的语句太大都会导致直接显示gone away。如果都是后面这个提示就好了,一目了然,用户自然会去修改max_allowed_packet。

    因此我们的问题就变成:为什么会有不同的提示?

 

分析1

  我们将报gone away的称为场景1,另外一个称为场景2.

  场景1执行的sql语句大小是16554913

  实际上场景2的返回信息是由MySQL服务端返回的,因为服务端才能判断得到包大小超过。那么场景1为什么不是相同的提示呢?是不是压根儿请求就没有发到服务端?

  照这个思路查到下面代码(clent/mysql.cc)

 

 

其中场景1执行到2785行return了,而场景2是在调用2786行的put_error中输出上述信息的。

 

  这证实了上面的结论,场景1是在调用请求的时候提示的失败,还没有到服务端判断包大小的环节。但是问题又来了,发送失败为什么要提示gone away?我们最常见到的gone away,是执行期间MySQL重启了,但这个case里面mysql并没有重启(这个很容易确认)。

 

分析1-2

进到mysql_real_query里面看看。发现执行路径差别在此(sql-common/client.c)

 

 

场景1调用net_write_command失败,会执行到行854,场景2调用成功。就是说场景2里面,整个语句是都发给服务端成功的,因此服务端可以做后续的判断(包大小)。而场景1由于发命令失败,执行到mysql_reconnect.。但进入mysql_reconnect发现没有必要重发(我们是普通的客户端),然后发现一处hard code。

 

 

         这里就是罪魁祸首了。因为mysql->reconnect为空,说明这里不需要重新连接。于是就直接在set_mysql_error中传入 CR_SERVER_GONE_ERROR, 输出在客户端就是gone away。

   至于为什么场景1发送会失败,关键就是内容太大,tcp都不让它发了(write调用失败)

 

追查2

其实笔者觉得这个问题反而比较有意义,gone away这种错误提示不友好,会导致追查很难下手。有一个固定的步骤来查,避免抓瞎。

从上面的分析知道,由于之前的调用失败,客户端试图进行“重连”,但是由于mysql->reconnect为0导致返回gone away。可以从这里下手。获取在执行mysql_reconnect之前的那个错误号。

一个debug命令文件

 

[dingqi.lxb@rds064076 master]$ cat x.debug

set args   -Srun/mysql.sock -uroot   test < b.sql
b mysql_reconnect
r
c
f 1
p mysql->net.last_errno

 

在shell执行 gdb mysql  -x x.debug
$1 = 1160

 

 这个1160就是我们要的了,

./include/mysqld_ername.h:{ “ER_NET_ERROR_ON_WRITE”, 1160, “Got an error writing communication packets” },

表明了真正的错误是交互时发包失败。

 

小结

    都是包太大,只是一个大过头了,导致在失败在客户端发生,又由于重连时的hard code,导致了一个不友好的提示 gone away。

    神马?你也碰到这种情况但不是max_allowed_packet 的问题,但是你的mysql没有debug信息?载一个源码安装。或者可以将你的复现步骤发给我。#异常gone away收集中#

0
0
分享到:
评论
2 楼 毛哥一号 2014-10-31  
大神 不知道 能不能看到我这个疑问
既然是客户端的问题,为什么会和服务端的max_allowed_packet这个参数有关系呢?
修改了服务端的这个参数,问题就解决了!
1 楼 xiaoxionglijie 2013-01-08  
在跑查询时,ctrl+c 在跑查询,就会报了。因为外要重连
root@lx 01:21:15>call sp_myddl;
^CCtrl-C -- sending "KILL QUERY 2985150" to server ...
Ctrl-C -- query aborted.
ERROR 2013 (HY000): Lost connection to MySQL server during query
root@lx 01:22:15>
root@lx 01:23:36>
root@lx 01:23:36>call sp_myddl;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    2985567
Current database: lx

相关推荐

    MySQL导入sql脚本错误:2006 解决方法

    MySQL导入sql脚本错误:2006 – MySQL ...最终找到原因,原来是MySQL导入大批量数据的时候超出了默认允许最大的数据包所以就提示2006 – MySQL server has gone away 于是找到my.cnf,在[mysqld]加入: max_allowed_pa

    MySQL server has gone away错误提示解决方法

    MySQL Server has gone away 是一个常见的错误提示,通常出现在MySQL服务器与客户端应用之间的连接中断时。这个错误可能由多种原因引起,包括超时、数据包过大或资源耗尽等。下面我们将详细探讨这些原因以及相应的...

    解决MySQL server has gone away错误的方案

    在我们使用mysql导入大文件sql时可能会报MySQL server has gone away错误,该问题是max_allowed_packet配置的默认值设置太小,只需要相应调大该项的值之后再次导入便能成功。该项的作用是限制mysql服务端接收到的包...

    gearman中worker常驻后台,导致MySQL server has gone away的解决方法

    在 Gearman 中,worker 运行在常驻后台模式,可能会遇到一个问题,即与 MySQL 数据库的连接在处理任务过程中因“MySQL server has gone away”而中断。这通常是由于多种原因造成的,包括 MySQL 服务宕机、超时、请求...

    mysql提示got timeout reading communication packets的解决方法

    MYSQL server has gone away 引起这个原因是不可怕的.原因是更改了系统的断开时间. mysql&gt;show gloable variables like “%timeout%”; 进行查看 interactive_timeout 的黓认值为28800 wait_timeout 的默认值这:...

    sql错误解决错误号:40error: 40

    在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: 命名管道提供程序, error: 40 - 无法打开到 ...

    101个MySQL的调节和优化方法

    以下是对“101个MySQL的调节和优化方法”这一主题的深入解析,涵盖从硬件配置到软件参数设置,以及查询优化等多个层面的知识点。 ### 硬件配置优化 1. **InnoDB缓存池大小调整**:根据服务器内存资源,合理设定`...

    全国手机号码段归属地数据库(记录条数共415284条记录)

    若导入时报错,ERROR 2006 (HY000):MySQL server has gone away 。我们可以通过语句查看一下允许的最大包大小:show global variables like 'max_allowed_packet'; MySQL使用最大数据包站站点进行服务器和客户端...

    oracle迁移mysql说明

    - 如果遇到“[ERR]2006-MySQL server has gone away”错误,这通常是由于数据包过大导致的。 - 解决方案: 1. 使用MySQL命令行客户端连接MySQL。 2. 查询当前`max_allowed_packet`的值: ```sql SHOW GLOBAL ...

    Qt5.4下连接Mysql,QSqlDatabase: QMYSQL driver not loaded but available-附件资源

    Qt5.4下连接Mysql,QSqlDatabase: QMYSQL driver not loaded but available-附件资源

    使用MySQL时的一些常见错误.docx

    本文将详细讨论两个常见的错误:“MySQL server has gone away”和“Can't connect to [local] MySQL server”。 首先,让我们关注“MySQL server has gone away”错误。这个错误通常意味着服务器在执行查询时超时...

    MYSQL

    Apache一起使用 MySQL 18 问题和常见的错误 18.1 如果 MySQL总是崩溃怎么办 18.2 使用 MySQL 时一些常见错误 18.2.1 MySQL server has gone away错误 18.2.2 Can't connect to [local] MySQL ...

Global site tag (gtag.js) - Google Analytics