错误 2006 (HY000): MySQL 服务器已消失

Posted

技术标签:

【中文标题】错误 2006 (HY000): MySQL 服务器已消失【英文标题】:ERROR 2006 (HY000): MySQL server has gone away 【发布时间】:2012-05-15 12:55:10 【问题描述】:

当我尝试获取大型 SQL 文件(大型 INSERT 查询)时出现此错误。

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。这些都不能解决问题。

这是我的最大数据包大小:

+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+

这是文件大小:

$ ls -s file.sql 
79512 file.sql

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

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

【问题讨论】:

这个文件有多大?是否可能超过 max_allowed_pa​​cket 设置? 好吧,不是这样。尝试从文件中提取单个查询并自己在监视器中运行它们。里面的东西导致崩溃/断开连接。 我从文件中随机提取的查询工作正常。我以编程方式生成了 SQL,并正确地转义了所有内容。所以我不确定如果有错误会导致什么错误。 我也有同样的问题... 【参考方案1】:
max_allowed_packet=64M

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

这在列的值很大时很有用,导致问题,你可以找到解释here。

在 Windows 上,此文件位于:“C:\ProgramData\MySQL\MySQL Server 5.6"

在 Linux (Ubuntu) 上:/etc/mysql

【讨论】:

这个解决方案为我解决了上述问题;仅通过客户端配置/选项无法完成任何操作,而且我不愿意通过 php 或其他方式进行编程解决方案。 您也可以以 root(或 SUPER 权限)登录数据库并执行set global max_allowed_packet=64*1024*1024; - 也不需要重启 MySQL 这为我解决了问题。 my.cnf 可以位于 /etc 文件夹中。 你应该可以把它放在命令行上,这样可以避免临时编辑系统文件:mysql --max_allowed_pa​​cket=1GM 对于任何寻找 my.cnf 文件位置的人,您可以查看this answer。也不要忘记通过键入:sudo service mysql restart重新启动 mysql,以使对 my.cnf 文件的更改生效。【参考方案2】:

你可以增加 Max Allowed Packet

SET GLOBAL max_allowed_packet=1073741824;

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

【讨论】:

这对我有用,而接受的答案却没有。我猜这个答案的更高价值是我解决方案的根源。 我在 my.cnf 中设置了 max_allowed_pa​​cket=1024M 那是服务器。您还需要在客户端中执行此操作,例如“mysql --max_allowed_pa​​cket=1073741824”。 这对我有用。一个问题是以字节为单位的“1073741824” 出于某种原因,即使在 my.cnf 上设置此变量也确实显示了默认配置转储的更改,运行 mysql -sve "SHOW VARIABLES LIKE 'max_allowed_pa​​cket'" 命令没有显示任何更改.只有这个答案上的命令正确更改了变量,我的导入成功完成。【参考方案3】:

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

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

【讨论】:

根据MySQL网站,标记的答案和this都应该使用。 更改这些设置后不要忘记重新加载配置文件或重新启动服务器 请记住,使用--max_allowed_packet 只会影响客户端。考虑修改 mysql 服务器 (mysqld) 以及通过编辑 /etc/my.cnf 文件中的 max_allowed_packet 并重新启动您的 mysql 服务器。 请注意,“50M”或“1G”的人性化值适用于 cli 和 my.cnf。 dev.mysql.com/doc/refman/8.0/en/using-system-variables.html【参考方案4】:

一般错误:

错误:2006 (CR_SERVER_GONE_ERROR) - MySQL 服务器已消失

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


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 服务器。

仔细检查该值是否由以下人员正确设置:

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 server has gone away。


调试

这里有一些专家级的调试想法:

检查日志,例如

sudo tail -f $(mysql -Nse "SELECT @@GLOBAL.log_error")

通过 mysqltelnet 或 ping 函数(例如 PHP 中的 mysql_ping)测试您的连接。

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

sudo tcpdump -i lo0 -s 1500 -nl -w- port mysql | strings

在 Linux 上,使用 strace。在 BSD/Mac 上使用 dtrace/dtruss,例如

sudo dtruss -a -fn mysqld 2>&1

见:Getting started with DTracing MySQL

了解更多如何调试 MySQL 服务器或客户端:26.5 Debugging and Porting MySQL。

作为参考,请查看sql-common/client.c 文件中负责为客户端命令引发CR_SERVER_GONE_ERROR 错误的源代码。

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;

【讨论】:

--quick 对我不起作用,但 --skip-extended-insert 起作用! 重要提示:确保变量在 [mysqld] 部分下,而不是 [mysql]。【参考方案5】:

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

    按照别人的建议创建了/etc/my.cnf,内容如下:

    [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 &lt; file.sql --verbose --force --wait --reconnect)。

重要提示:必须执行这两个步骤,因为如果我不费心对 /etc/my.cnf 文件进行更改以及附加这些标志,那么导入后会丢失一些表。

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

【讨论】:

即使按照所有说明操作,我仍然收到错误消息。 对于那些在共享主机中运行此问题且无法更改配置文件的人,此解决方案非常有效。 @SantoshHegde 可能为时已晚,但在您更改my.cnf 后,您需要重新启动您的mysql 服务。 仅供参考,max_allowed_packet 不能超过 1GB1024M,在 MySQL 5.7+ 上,net_buffer_length 会根据数据包设置自动缩放(不要设置)。最后,connect_timeout 不应该与此错误相关,但其他超时设置可能是,特别是 wait_timeoutinteractive_timeout... 如果这些调整都不起作用,请尝试将您的服务器升级到更多 RAM 内存;) 【参考方案6】:

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

$> mysqladmin variables -u user -p 

这将显示当前变量,在本例中为 max_allowed_pa​​cket,正如有人在另一个答案中所说,您可以使用

临时设置它
mysql> SET GLOBAL max_allowed_packet=1072731894

在我的例子中,cnf 文件没有被考虑在内,我不知道为什么,所以 SET GLOBAL 代码真的很有帮助。

【讨论】:

很高兴能够一口气看到所有的配置设置。谢谢!【参考方案7】:

您也可以以root(或超级权限)登录数据库并执行

set global max_allowed_packet=64*1024*1024;

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

[mysqld]
max_allowed_packet=64M

并在重启 MySQL 后确认更改:

show variables like 'max_allowed_packet';

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

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

【讨论】:

【参考方案8】:

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

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

[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

块引用

【讨论】:

太棒了。这有助于我解决另一个可以解决的错误:)【参考方案9】:

我遇到了同样的问题,但在 [mysqld] 下的 my.ini/my.cnf 文件中更改 max_allowed_pa​​cket 就成功了。

添加一行

max_allowed_packet=500M

完成后现在重新启动 MySQL 服务。

【讨论】:

@babonk 是的,但是这个答案更有用,因为它说明了它需要去的部分【参考方案10】:

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

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

$ mysql db_name

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

【讨论】:

另一件事值得一提的是,我几乎在source 命令之后立即收到错误 如果您在 source 命令之后立即收到错误,那么很可能 MySQL 不喜欢该查询的某些内容。你检查过一般日志吗? 我必须弄清楚如何检查一般日志。我在 MAMP 上,但我不确定它是否默认写入。 我选择通过 PHP 查询和切片来解决它。【参考方案11】:

如果您在 Mac 上并像我一样通过 brew 安装了 mysql,则以下操作有效。

    cp $(brew --prefix mysql)/support-files/my-default.cnf /usr/local/etc/my.cnf

来源:For homebrew mysql installs, where's my.cnf?

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

    mysql.server restart

【讨论】:

【参考方案12】:

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

ndb_mgm -e 'ALL REPORT MEMORYUSAGE'

而且 mysqld 也可以正常工作。所以一开始我不明白出了什么问题。大约 5 分钟后,ndb_mgm 结果显示没有数据节点工作。然后我意识到问题所在。因此,尝试重新启动所有数据节点,然后 mysql 服务器又回来了,一切正常。

但有一点很奇怪,在我丢失mysql服务器进行一些查询后,当我使用show tables之类的cmd时,我仍然可以获得33 rows in set (5.57 sec)之类的返回信息,但没有显示表信息。

【讨论】:

【参考方案13】:

当您使用与转储中使用的不同的 COLLATION 创建 SCHEMA 时,也会出现此错误消息。所以,如果转储包含

CREATE TABLE `mytab` (
..
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

您还应该在 SCHEMA 排序规则中反映这一点:

CREATE SCHEMA myschema COLLATE utf8_unicode_ci;

我一直在架构中使用 utf8mb4_general_ci,因为我的脚本来自全新的 V8 安装,现在在旧 5.7 上加载数据库崩溃了,几乎让我发疯。

所以,也许这可以帮助您节省一些令人沮丧的时间... :-)

(MacOS 10.3,mysql 5.7)

【讨论】:

【参考方案14】:

我在 XAMMP 中遇到了同样的问题

Metode-01:我更改了D:\xampp\mysql\bin\my.ini 文件中的 max_allowed_pa​​cket,如下所示:

ma​​x_allowed_pa​​cket=500M

最后重启一次 MySQL 服务就完成了。

Metode-02:

如果您使用的是 XAMPP,则更简单。打开XAMPP控制面板,点击mysql部分的config按钮。

现在单击 my.ini,它将在编辑器中打开。将 max_allowed_pa​​cket 更新为您需要的大小。

然后重启mysql服务。单击 Mysql 服务上的停止,再次单击启动。等待几分钟。

然后尝试再次运行您的 Mysql 查询。希望它会起作用。

【讨论】:

【参考方案15】:

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

联系服务器管理员并让他们诊断问题。任何非恶意 SQL 都不应该导致服务器崩溃,mysqldump 的输出当然也不应该。

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

【讨论】:

换句话说,这个错误可能是由于服务器没有足够的RAM内存来完成导入...升级应该可以解决它。【参考方案16】:

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

【讨论】:

【参考方案17】:

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

【讨论】:

如果您使用 Amazon RDS,这可行。您不能像 SebaGra 指示的那样在 RDS 中设置全局值,如果您去修改数据库的自定义参数组,找到 max_allowed_packet parameter 并将其设置为适当的大小(或者如果您有非常大的 blob,只需将其设置为最大值 1073741824) 它应该可以工作。 在加载相同的数据集或完全随机时,您是否遇到了一致的失败?问是因为我有同样的问题,但它完全随机,会失败 5 次,然后在第 5 次工作。此外,移动到我的本地机器并从 Visual Studio 运行似乎有帮助,但我仍然会偶尔遇到错误。【参考方案18】:

对于寻求数据库导入失败解决方案的 Drupal 8 用户:

在 sql 转储文件的末尾可以有将数据插入“webprofiler”表的命令。 那是我猜一些调试日志文件,对于站点工作并不重要,因此可以删除所有这些。我删除了所有这些插入,包括 LOCK TABLES 和 UNLOCK TABLES(以及介于两者之间的所有内容)。它位于 sql 文件的最底部。此处描述了问题:

https://www.drupal.org/project/devel/issues/2723437

但除了截断该表之外没有其他解决方案。

顺便说一句,我尝试了上述答案中的所有解决方案,但没有其他帮助。

【讨论】:

【参考方案19】:

以上方法我都试过了,都失败了。

我最终使用了-h 127.0.0.1,而不是使用默认的var/run/mysqld/mysqld.sock

【讨论】:

【参考方案20】:

如果您尝试过所有这些解决方案,尤其是。将 max_allowed_packet 增加到支持的最大数量 1GB 并且您仍然看到这些错误,这可能是您的服务器实际上没有足够的可用 RAM 内存...

解决方案 = 将您的服务器升级到更多 RAM 内存,然后重试。

注意:我很惊讶这个简单的解决方案在这个线程讨论了 8 年多之后仍然没有被提及......有时我们的开发人员往往会想太多。

【讨论】:

【参考方案21】:

max_allowed_packet=64M 添加到[mysqld]

[mysqld] 
max_allowed_packet=64M

重启 MySQL 服务器。

【讨论】:

【参考方案22】:

消除触发警告的错误是我的最终解决方案。我还更改了 max_allowed_pa​​cket,它有助于处理有错误的较小文件。消除错误也极大地加快了进程。

【讨论】:

“消除触发警告的错误是我的最终解决方案”——这是什么意思?我在给定问题中没有看到任何警告 @Basil “消除错误”始终是解决问题的方法。请更准确,并在回答时提供详细信息。 这并没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review【参考方案23】:

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

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

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

然后你只备份数据,然后做同样的事情,它就会起作用。

【讨论】:

【参考方案24】:

这样使用mysql客户端怎么样:

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

【讨论】:

如果 sql 文件太大,这将不起作用......这就是问题所在。

以上是关于错误 2006 (HY000): MySQL 服务器已消失的主要内容,如果未能解决你的问题,请参考以下文章

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

将 Laravel 连接到 XAMPP MySQL (MariaDB) 数据库 SQLSTATE[HY000] [2006] MySQL 服务器已消失

MySQLMySQL错误“ERROR 2006 (HY000):MySQL server has gone away”

解决MySQL报错:ERROR 2006 (HY000): MySQL server has gone away No connection(图文并茂)

解决MySQL报错:ERROR 2006 (HY000): MySQL server has gone away No connection(图文并茂)

[故障解决]Mysql爆出ERROR 2006 (HY000): MySQL server has gone away的错误怎么办?