导入大型 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_packet 和 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_packet。在 Debian 上:
sudo nano /etc/mysql/my.cnf
,设置max_allowed_packet = 64M
(你可以 当错误 2006 消失时调整/减小此值),然后sudo /etc/init.d/mysql restart
。
编辑:
请注意,MySQL 选项文件的命令尚未作为 cmets 提供(例如在 php.ini 中)。因此,您必须在my.cnf
或my.ini
中键入任何更改/调整,并将它们放在mysql/data
目录或任何其他路径中,在适当的选项组下,例如[client]
、[myslqd]
等。例如:
[mysqld]
wait_timeout = 600
max_allowed_packet = 64M
然后重新启动服务器。要获取它们的值,请输入 mysql 客户端:
> select @@wait_timeout;
> select @@max_allowed_packet;
【讨论】:
在我的例子中是 max_allowed_packet 变量。它被设置为默认值 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_packet = 64M【参考方案4】:如果您使用默认值运行,那么您有很大的空间来优化您的 mysql 配置。
我建议的第一步是将 max_allowed_packet 增加到 128M。
然后下载MySQL Tuning Primer script 并运行它。它将为您的配置的多个方面提供建议,以获得更好的性能。
还要考虑在 MySQL 和 PHP 中调整您的超时值。
您要导入的文件有多大(文件大小),您是否能够使用 mysql 命令行客户端而不是 PHPMyAdmin 来导入该文件?
【讨论】:
谢谢,我已经将 max_allowed_packet 设置为 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_packet”行添加到 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_packet”更新为 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_packet = 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_packet
在任何适合您的情况下,它应该是任意数字 * 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 服务器已消失的主要内容,如果未能解决你的问题,请参考以下文章