ERROR 2006(HY000):MySQL服务器已经消失

ERROR 2006 (HY000): MySQL server has gone away

当我尝试获取大型SQL文件(一个大的INSERT查询)时,我收到此错误。

1
2
3
4
5
6
7
8
9
10
mysql>  source file.sql
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    2
Current database: *** NONE ***

ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    3
Current database: *** NONE ***

表中没有任何内容更新。 我已经尝试删除和取消删除表/数据库,以及重新启动MySQL。 这些都不能解决问题。

这是我的最大包大小:

1
2
3
4
5
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+

这是文件大小:

1
2
$ ls -s file.sql
79512 file.sql

当我尝试其他方法时......

1
2
3
$ ./mysql -u root -p my_db < file.sql
Enter password:
ERROR 2006 (HY000) at line 1: MySQL server has gone away


1
max_allowed_packet=64M

将此行添加到my.cnf文件中可以解决我的问题。

当列具有较大的值(这会导致问题)时,这很有用,您可以在此处找到解释。

On Windows this file is located at:"C:\ProgramData\MySQL\MySQL Server
5.6"

On Linux (Ubuntu): /etc/mysql


您可以增加最大允许数据包

1
SET GLOBAL max_allowed_packet=1073741824;

http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_max_allowed_pa??cket


由于某种原因,全局更新和my.cnf设置对我不起作用。将max_allowed_packet值直接传递给客户端在此工作:

1
mysql -h <hostname> -u username -p --max_allowed_packet=1073741824 <databasename> < db.sql


一般来说错误:

Error: 2006 (CR_SERVER_GONE_ERROR) - MySQL server has gone away

表示客户端无法向服务器发送问题。

mysql导入

在您通过mysql导入数据库文件的特定情况下,这很可能意味着SQL文件中的某些查询太大而无法导入而无法在服务器上执行,因此客户端在第一次发生时失败错误。

所以你有以下几种可能性:

  • mysql添加强制选项(-f)以继续并执行其余查询。

    如果数据库有一些与缓存无关的大型查询,则这很有用。

  • 在服务器配置中增加max_allowed_packetwait_timeout(例如~/.my.cnf)。

  • 使用--skip-extended-insert选项转储数据库以分解大型查询。然后再次导入它。

  • 尝试为mysql应用--max-allowed-packet选项。

常见原因

一般来说,这个错误可能意味着几件事,例如:

  • 对服务器的查询不正确或太大,

    解决方案:增加max_allowed_packet变量。

    • 确保变量位于[mysqld]部分,而不是[mysql]

    • 不要害怕使用大数字进行测试(如1G)。

    • 不要忘记重启MySQL / MariaDB服务器。

    • 仔细检查值是否正确设置:

      1
      2
      mysql -sve"SELECT @@max_allowed_packet" # or:
      mysql -sve"SHOW VARIABLES LIKE 'max_allowed_packet'"
  • 您从客户端的TCP / IP连接获得超时。

    解决方案:增加wait_timeout变量。

  • 您尝试在关闭服务器连接后运行查询。

    解决方案:应纠正应用程序中的逻辑错误。

  • 主机名查找失败(例如DNS服务器问题),或者服务器已使用--skip-networking选项启动。

    另一种可能性是您的防火墙阻止MySQL端口(例如默认情况下为3306)。

  • 正在运行的线程已被杀死,因此请重试。

  • 您遇到了执行查询时服务器死机的错误。

  • 在不同主机上运行的客户端没有必要的连接权限。

  • 还有更多,所以在以下方面了解更多:B.5.2.9 MySQL服务器已经消失。

调试

以下是一些专家级调试思路:

  • 检查日志,例如

    1
    sudo tail -f $(mysql -Nse"SELECT @@GLOBAL.log_error")
  • 通过mysqltelnet或ping函数测试连接(例如PHP中的mysql_ping)。

  • 使用tcpdump来嗅探MySQL通信(不适用于套接字连接),例如:

    1
    sudo tcpdump -i lo0 -s 1500 -nl -w- port mysql | strings
  • 在Linux上,使用strace。在BSD / Mac上使用dtrace / dtruss,例如

    1
    sudo dtruss -a -fn mysqld 2>&1

    请参阅:DTracing MySQL入门

了解更多如何在以下位置调试MySQL服务器或客户端:26.5调试和移植MySQL。

作为参考,检查sql-common/client.c文件中的源代码,该文件负责抛出客户端命令的CR_SERVER_GONE_ERROR错误。

1
2
3
4
5
6
7
MYSQL_TRACE(SEND_COMMAND, mysql, (command, header_length, arg_length, header, arg));
if (net_write_command(net,(uchar) command, header, header_length,
          arg, arg_length))
{
  set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
  goto end;
}


以防万一,检查你可以使用的变量

1
$> mysqladmin variables -u user -p

这将显示当前变量,在本例中为max_allowed_pa??cket,并且正如有人在另一个答案中所说,您可以暂时设置它

1
mysql> SET GLOBAL max_allowed_packet=1072731894

在我的情况下,没有考虑cnf文件,我不知道为什么,所以SET GLOBAL代码确实有帮助。


我通过按顺序执行以下两个步骤解决了错误ERROR 2006 (HY000) at line 97: MySQL server has gone away并成功迁移了> 5GB的sql文件:

  • 像其他人推荐的那样创建/etc/my.cnf,其内容如下:

    1
    2
    3
    4
    5
    [mysql]
    connect_timeout = 43200
    max_allowed_packet = 2048M
    net_buffer_length = 512M
    debug-info = TRUE
  • 将标志--force --wait --reconnect附加到命令(即mysql -u root -p -h localhost my_db < file.sql --verbose --force --wait --reconnect)。

  • 重要说明:必须执行这两个步骤,因为如果我不打算对/etc/my.cnf文件进行更改以及附加这些标志,则导入后会丢失一些表。

    使用的系统:OSX El Capitan 10.11.5; mysql Ver 14.14 for osx10.8(i386)发布5.5.51


    您也可以以root用户身份(或SUPER权限)登录数据库并执行此操作

    1
    set global max_allowed_packet=64*1024*1024;

    也不需要MySQL重启。请注意,您应该按照其他解决方案中的说明修复my.cnf文件:

    1
    2
    [mysqld]
    max_allowed_packet=64M

    并在重新启动MySQL后确认更改:

    1
    show variables like 'max_allowed_packet';

    您也可以使用命令行,但这可能需要更新启动/停止脚本,这些脚本可能无法在系统更新和修补程序中使用。

    根据要求,我在这里添加自己的答案。很高兴看到它的作品!


    我有同样的问题,但在[mysqld]下的my.ini / my.cnf文件中更改max_allowed_pa??cket就成了伎俩。

    添加一行

    1
    max_allowed_packet=500M

    完成后立即重启MySQL服务。


    解决方案是在[mysqld]标记下的选项文件中为wait_timeoutconnect_timeout参数增加值。

    我不得不恢复400MB的mysql备份,这对我有用(我在下面使用的值有点夸张,但你明白了):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [mysqld]
    port=3306
    explicit_defaults_for_timestamp = TRUE
    connect_timeout = 1000000
    net_write_timeout = 1000000
    wait_timeout = 1000000
    max_allowed_packet = 1024M
    interactive_timeout = 1000000
    net_buffer_length = 200M
    net_read_timeout = 1000000
    set GLOBAL delayed_insert_timeout=100000

    Blockquote


    这里可能会发生一些事情;

    • 您的INSERT运行时间很长,客户端正在断开连接。当它重新连接时,它没有选择数据库,因此错误。这里的一个选项是从命令行运行批处理文件,并在参数中选择数据库,如下所示;

    $ mysql db_name < source.sql

    • 另一种方法是通过php或其他语言运行命令。在每个长时间运行的语句之后,您可以关闭并重新打开连接,确保在每个查询开始时连接。


    如果你在Mac上并像我一样通过brew安装mysql,以下工作。

  • cp $(brew --prefix mysql)/support-files/my-default.cnf /usr/local/etc/my.cnf
  • 来源:对于自制的mysql安装,哪里是my.cnf?

  • max_allowed_packet=1073741824添加到/usr/local/etc/my.cnf

  • mysql.server restart


  • 我使用Mysql Cluster时遇到此错误,我不知道这个问题是否来自群集使用。由于错误完全相同,所以在这里给出我的解决方案。
    获取此错误是因为数据节点突然崩溃。但是当节点崩溃时,您仍然可以使用cmd获得正确的结果:

    1
    ndb_mgm -e 'ALL REPORT MEMORYUSAGE'

    并且mysqld也能正常工作。起初,我无法理解错误。大约5分钟后,ndb_mgm结果显示没有数据节点正常工作。然后我意识到了这个问题。因此,尝试重新启动所有数据节点,然后mysql服务器又回来了,一切正常。

    但有一件事对我来说很奇怪,在我丢失mysql服务器进行某些查询之后,当我使用像show tables这样的cmd时,我仍然可以得到像33 rows in set (5.57 sec)这样的返回信息,但是没有显示表格信息。


    对于amazon RDS(这是我的情况),您可以将max_allowed_packet参数值更改为以字节为单位的任何数值,这对于您可能具有的任何插入中的最大数据有意义(例如:如果插入中有大约50mb blob值 ,在新的或现有的parameter-group中设置max_allowed_packet为64M = 67108864。 然后将该参数组应用于您的MySQL实例(可能需要重新启动实例)。


    这是一个非常罕见的问题,但是如果有人将整个/ var / lib / mysql目录复制为将数据库迁移到另一台服务器的方法,我已经看到了这一点。 它不起作用的原因是因为数据库正在运行并使用日志文件。 如果/ var / log / mysql中有日志,它有时不起作用。 解决方案是复制/ var / log / mysql文件。


    如果它重新连接并获得连接ID 2,则服务器几乎肯定会崩溃。

    联系服务器管理员并让他们诊断问题。没有非恶意SQL应该崩溃服务器,mysqldump的输出肯定不应该。

    可能的情况是,服务器管理员已经发生了一些大的操作错误,例如分配大于体系结构的地址空间限制的缓冲区大小,或者超过虚拟内存容量。 MySQL错误日志可能会有一些相关信息;如果他们有能力,他们会监督这个。


    如果这些答案都没有解决您的问题,我通过删除表并以这种方式自动重新创建它来解决它:

    1
    2
    3
    4
    5
    when creating the backup, first backup structure and be sure of add:
    DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT
    CREATE PROCEDURE / FUNCTION / EVENT
    IF NOT EXISTS
    AUTO_INCREMENT

    然后只需将此备份与您的数据库一起使用,它将删除并重新创建您需要的表。

    然后你只备份数据,并做同样的事情,它会工作。


    如何使用这样的mysql客户端:

    1
    mysql -h <hostname> -u username -p <databasename> < file.sql