导入大型 sql 文件时 MySQL 服务器已消失

Posted

技术标签:

【中文标题】导入大型 sql 文件时 MySQL 服务器已消失【英文标题】:MySQL Server has gone away when importing large sql file 【发布时间】:2017-03-17 05:30:58 【问题描述】:

我试图通过 phpMyAdmin 导入一个大的 sql 文件...但它一直显示错误

'mysql 服务器已经消失'

怎么办?

【问题讨论】:

max_allowed_pa​​cket 和 wait_timeout 的值是多少? 你可以尝试加倍max_allowed_packet。有点粗糙,但如果可行,您可以找到一个合理的值。 感谢科尔约翰逊的笑声。这太棒了!哈哈! :) 我经常偶然看到它。但我无法再次重现相同的错误。并且,因此意识到它可能是动态的。有时,如果客户端向服务器发送了太多 SQL(例如,来自循环),就会发生这种情况。找到此错误的实际原因很重要。检查您的查询日志以查找重复的 SQL 模式以找出线索。 有时当你的磁盘空间不足时你会得到这个 【参考方案1】:

如here所述:

MySQL 服务器的两个最常见原因(和修复)已消失 (错误 2006)是:

服务器超时并关闭连接。如何解决:

    检查 mysqld 的 my.cnf 配置文件中的 wait_timeout 变量是否足够大。在 Debian 上:sudo nano /etc/mysql/my.cnf,设置 wait_timeout = 600 秒(你可以 当错误 2006 消失时调整/减小此值),然后 sudo /etc/init.d/mysql restart。我没有检查,但默认值 wait_timeout 可能约为 28800 秒(8 小时)。

    服务器丢弃了不正确或太大的数据包。如果 mysqld 收到一个太大或不正确的数据包,它会假设某些东西有 客户端出错并关闭连接。你可以增加 通过增加值来限制最大数据包大小 my.cnf 文件中的 max_allowed_pa​​cket。在 Debian 上:sudo nano /etc/mysql/my.cnf,设置 max_allowed_packet = 64M(你可以 当错误 2006 消失时调整/减小此值),然后sudo /etc/init.d/mysql restart

编辑:

请注意,MySQL 选项文件的命令尚未作为 cmets 提供(例如在 php.ini 中)。因此,您必须在my.cnfmy.ini 中键入任何更改/调整,并将它们放在mysql/data 目录或任何其他路径中,在适当的选项组下,例如[client][myslqd] 等。例如:

[mysqld]
wait_timeout = 600
max_allowed_packet = 64M

然后重新启动服务器。要获取它们的值,请输入 mysql 客户端:

> select @@wait_timeout;
> select @@max_allowed_packet;

【讨论】:

在我的例子中是 max_allowed_pa​​cket 变量。它被设置为默认值 1 MB(您可以通过运行SHOW VARIABLES MySQL 查询来查看这一点),并且我正在导入的文件有一些非常大的记录。我打开 my.ini 文件(我正在运行 Windows)并将值设置为:max_allowed_packet = 64M,重新启动 MySQL 并重新运行导入。 成功了!请注意,在 (windows) xampp 安装上,my.ini 文件将位于 xampp/mysql/bin/my.ini 我找不到wait_timeout 请注意 my.ini 文件包含 max_allowed_packet 的 2 个值。改变两者,只是为了确定。我犯了一个错误,只更改了max_allowed_packet 的第二个值,而不是寻找其他值。这让我承受了 30 分钟的压力。 windows(使用 Xampp)是 my.ini 文件和 innodb_lock_wait_timeout【参考方案2】:

对我来说,这个解决方案没有奏效,所以我执行了

SET GLOBAL max_allowed_packet=1073741824;

在我的 SQL 客户端中。

如果在运行 MYSql 服务的情况下无法更改,则应停止服务并更改“my.ini”文件中的变量。

例如:

max_allowed_packet=20M

【讨论】:

这在 MAMP (OS X) 上对我有用,而其他更流行的答案却没有。但它是永久的吗? @atwixtor 不,像这样设置变量直到服务器重新启动。然后它们被重置为默认值。 成功了,在 Windows 上的测试 XAMPP 机器上,我必须同时修改 php.ini 文件(如答案中的@GBD 所建议)和 MySQL 配置文件 my.ini 以使它工作。 我建议添加您可以使用SHOW variables LIKE 'max_allowed_packet'检查当前大小 这不是 permanent,因为该值将在服务器重新启动(最终)时重置,但它也不仅仅适用于当前会话。在一个客户端中设置max_allowed_packet,然后在另一个会话中导入大的.sql 文件可以正常工作。【参考方案3】:

如果您正在使用 XAMPP,那么您可以通过以下更改修复 MySQL 服务器已消失的问题。

打开您的 my.ini 文件 my.ini 位置是 (D:\xampp\mysql\bin\my.ini)

更改以下变量值

max_allowed_packet = 64M
innodb_lock_wait_timeout = 500

【讨论】:

samp for wamp, max_allowed_pa​​cket = 64M【参考方案4】:

如果您使用默认值运行,那么您有很大的空间来优化您的 mysql 配置。

我建议的第一步是将 max_allowed_pa​​cket 增加到 128M。

然后下载MySQL Tuning Primer script 并运行它。它将为您的配置的多个方面提供建议,以获得更好的性能。

还要考虑在 MySQL 和 PHP 中调整您的超时值。

您要导入的文件有多大(文件大小),您是否能够使用 mysql 命令行客户端而不是 PHPMyAdmin 来导入该文件?

【讨论】:

谢谢,我已经将 max_allowed_pa​​cket 设置为 16M,然后发现这个问题并将其提高到 32M,认为这肯定足够了,但后来看到你的答案,128M 肯定有效。我正在收集 *.sql 文件中的整个 SQL 语句被视为一个数据包?【参考方案5】:

如果您在 OS X 上使用 MAMP,则需要更改 MySQL 模板中的 max_allowed_packet 值。

    您可以在以下位置找到它:文件 > 编辑模板 > MySQL my.cnf

    然后只需搜索max_allowed_packet,更改值并 保存。

【讨论】:

【参考方案6】:

我用这个简短的 /etc/mysql/my.cnf 文件解决了我的问题:

[mysqld]
wait_timeout = 600
max_allowed_packet = 100M

【讨论】:

确认这也适用于 WAMP 上的 MySQL v5.6.12:在 Windows 上,将上面的“wait_timeout”和“max_allowed_pa​​cket”行添加到 wamp\bin\mysql\mysql_version\ 的 [mysqld] 部分我的.ini 感谢@dan 解决了我多年前的问题哈哈,我从未在[mysqld] 部分添加这些设置 这适用于 MySQL v5.7。 my-default.ini 不是默认创建的,所以你需要创建它。【参考方案7】:

当我导入 16 GB 的 SQL 文件时,我遇到了这个错误和其他相关错误。对我来说,编辑 my.ini 并在 [mysqld] 部分设置以下内容(基于几个不同的帖子):

max_allowed_packet      = 110M
innodb_buffer_pool_size=511M
innodb_log_file_size=500M
innodb_log_buffer_size = 800M
net_read_timeout        = 600
net_write_timeout       = 600

如果您在 Windows 下运行,请转到控制面板、服务,然后查看 MySQL 的详细信息,您将看到 my.ini 的位置。然后编辑保存my.ini后,重启mysql服务(或者重启电脑)。

如果您使用的是 HeidiSQL,您也可以使用它设置部分或全部。

【讨论】:

【参考方案8】:

发生这种情况的另一个原因是内存不足。检查 /var/log/messages 并确保您的 my.cnf 未设置为导致 mysqld 分配比您的机器更多的内存。

你的mysqld进程实际上可以被内核杀死,然后在你没有意识到的情况下被“safe_mysqld”进程重新启动。

使用 top 并在它运行时观察内存分配,看看你的余量是多少。

在更改之前备份 my.cnf。

【讨论】:

这就是导致我的问题的原因。我添加了一个 1GB 的交换文件,它完全修复了它。【参考方案9】:

我将“max_allowed_pa​​cket”更新为 1024M,但仍然无法正常工作。原来我的部署脚本正在运行:

mysql --max_allowed_packet=512M --database=mydb -u root < .\db\db.sql

如果您使用这种方式,请务必在命令行中明确指定一个更大的数字。

【讨论】:

【参考方案10】:

如果您的数据包含BLOB 数据:

请注意,从命令行导入数据似乎会阻塞 BLOB 数据,从而导致“MySQL 服务器已消失”错误。

为避免这种情况,请重新创建 mysqldump,但使用 --hex-blob 标志:

http://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_hex-blob

这将用十六进制值而不是其他文本中的二进制写出数据文件。

PhpMyAdmin 还有一个选项“以十六进制表示法转储二进制列(例如,“abc”变为 0x616263)”,效果很好。

请注意,存在一个长期存在的错误(截至 2015 年 12 月),这意味着 GEOM 列未转换: Back up a table with a GEOMETRY column using mysqldump? 所以使用像 PhpMyAdmin 这样的程序似乎是唯一的解决方法(上面提到的选项确实可以正确转换 GEOM 列)。

【讨论】:

【参考方案11】:

我遇到了同样的问题

$image_base64 = base64_encode(file_get_contents($_FILES['file']['tmp_name']) );
$image = 'data:image/jpeg;base64,'.$image_base64;
$query = "insert into images(image) values('".$image."')";
mysqli_query($con,$query);

在 phpmyadmin 的 \xampp\mysql\bin\my.ini 文件中我们只得到

[mysqldump]
max_allowed_packet=110M

这仅适用于 mysqldump -u root -p dbname 。我通过用

替换上面的代码解决了我的问题
max_allowed_packet=110M
[mysqldump]
max_allowed_packet=110M

【讨论】:

【参考方案12】:

如果需要很长时间才能失败,则放大wait_timeout 变量。

如果立即失败,请放大max_allowed_packet 变量;它仍然不起作用,请确保该命令是有效的 SQL。我的有未转义的引号,这把一切都搞砸了。

此外,如果可行,请考虑将单个 SQL 命令的插入次数限制为 1000 次。您可以创建一个脚本,通过重新引入 INSERT... 部分来从单个语句中创建多个语句,每 n 次插入.

【讨论】:

【参考方案13】:

我遇到了类似的错误。要解决这个问题,只需打开 my.ini 文件。在第 36 行更改最大允许数据包大小的值,即。 max_allowed_pa​​cket = 20M

【讨论】:

【参考方案14】:

确保 mysqld 进程不会因为 systemd 等服务管理器而重新启动。

我在使用 centos 7 的 vagrant 中遇到了这个问题。配置调整没有帮助。原来是systemd每次占用太多内存时都会杀死mysqld服务。

【讨论】:

【参考方案15】:

我今天在复制数据库时遇到了类似的错误(MySQL 服务器已经消失...),但是当我尝试重新启动 mysql.server restart 时出现错误

ERROR! The server quit without updating PID ...

我是这样解决的: 我打开 Applications/Utilities/ 并运行 Activity Monitor

 quit mysqld

然后能够解决错误问题

mysql.server restart

【讨论】:

【参考方案16】:

我正在做一些大型计算,这涉及到 mysql 连接要保持很长时间并且数据量很大。我正面临这个“Mysql go away issue”。所以我尝试优化查询,但这对我没有帮助,然后我增加了默认设置为较低值的 mysql 变量限制。

wait_timeout max_allowed_pa​​cket

在任何适合您的情况下,它应该是任意数字 * 1024(字节)。您可以使用 'mysql -u username - p' 命令登录到终端,并可以检查和更改这些变量限制。

【讨论】:

【参考方案17】:

对于 GoDaddy 共享主机

在 GoDaddy 共享主机帐户上,调整 PHP.ini 等文件很棘手。但是,还有另一种方法,它对我来说非常有效。 (我刚刚成功上传了一个 3.8Mb 的 .sql 文本文件,包含 3100 行和 145 列。在 phpMyAdmin 中使用 IMPORT 命令,我得到了可怕的 MySQL server has gone away 错误,没有更多信息.)

我发现 Matt Butcher 的答案是正确的。像马特一样,我尝试了各种技巧,从以一口大小的块导出 MySQL 数据库,到编写将大型导入分解为较小导入的脚本。但这是有效的:

(1) CPANEL ---> 文件(组)---> 备份

(2a) 在“部分备份”标题下... (2b) 在“下载 MySQL 数据库备份”下 (2c) 选择您的数据库并下载备份(此步骤可选,但很明智)

(3a) 直接在 2b 右侧,在“恢复 MySQL 数据库备份”标题下 (3b) 从本地驱动器中选择 .SQL 导入文件 (3c) 真正的幸福将属于你(很快......)我的大约花了 5 秒

我能够使用此方法导入单个表。我的数据库中没有其他任何东西受到影响——但这就是上面第 (2) 步的目的。

注意事项: 一种。如果您不确定如何创建 .SQL 导入文件,请使用 phpMyAdmin 导出表并修改该文件结构。

来源: Matt Butcher 2010 Article

【讨论】:

好的,所以立即投反对票,但没有评论为什么。此信息对某人不起作用吗?如果是这样,请分享-它对我有用,这就是我添加此答案的原因。上面的其他答案对我不起作用,但这个解决方案确实有效。那么为什么要投反对票呢?如果您在 GoDaddy 上并且这对您不起作用,我想知道以便我可以提供帮助。但是,如果您不使用 GoDaddy 共享主机,为什么仅仅因为它不适用于 ,您会否决这个答案?【参考方案18】:

如果增加max_allowed_packet 没有帮助。

通过 Sequel Pro 将 .sql 文件导入我的数据库时,我遇到了与您相同的错误。

max_allowed_packet 升级为512M 后错误仍然存​​在,所以我在命令行中运行导入,而不是:

mysql --verbose -u root -p DatabaseName < MySQL.sql

它给出了以下错误:

ASCII '\0' appeared in the statement, but this is not allowed unless option --binary-mode is enabled

我发现了几个有用的 *** 问题:

Enable binary mode while restoring a Database from an SQL dump Mysql ERROR: ASCII '\0' while importing sql file on linux server

在我的情况下,我的 .sql 文件有点损坏或什么的。我们得到的 MySQL 转储包含两个 zip 文件,需要将它们连接在一起然后解压缩。我认为解压缩最初被中断,使文件带有一些奇怪的字符和编码。获取一个新的 MySQL 转储并正确解压缩它对我有用。

只是想在此处添加它,以防其他人发现增加 max_allowed_packet 变量没有帮助。

【讨论】:

【参考方案19】:

关于数据包大小或超时的解决方案对我没有任何影响。我需要禁用 ssl

mysql -u -p -hmyhost.com --disable-ssl db < file.sql

https://dev.mysql.com/doc/refman/5.7/en/encrypted-connections.html

【讨论】:

以上是关于导入大型 sql 文件时 MySQL 服务器已消失的主要内容,如果未能解决你的问题,请参考以下文章

导入大型 sql 文件时 MySQL 服务器已消失

导入大型 sql 文件时 MySQL 服务器已消失

导入大型 sql 文件时 MySQL 服务器已消失

MySQL导入导致“服务器已消失”错误[重复]

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

#2006 - MySQL 服务器已在 db 导入时消失