即使使用 max_allowed_packet 参数,使用 mysqldump 时也会失去与 mysql 的连接

getting Lost connection to mysql when using mysqldump even with max_allowed_packet parameter

我想在我的远程服务器数据库中转储特定的 table,这工作正常,但是 table 之一是 900 万行,我得到:

Lost connection to MySQL server during query when dumping table `table_name` at row: 2002359

所以在网上阅读后我明白我需要增加我的 max_allowed_packet,并且可以将它添加到我的命令中。

所以我 运行 以下命令转储我的 table:

mysqldump -uroot -h my.host -p'mypassword' --max_allowed_packet=512M db_name table_name | gzip  > dump_test.sql.gz

出于某种原因,我仍然得到:

Lost connection to MySQL server during query when dumping table `table_name` at row: 2602499

我做错了什么吗?

这很奇怪,只有 900 万条记录...不太大。

尝试将 --quick 选项添加到您的 mysqldump 命令;它在 table 大的情况下效果更好。它将结果集中的行流式传输到输出,而不是吞噬整个 table,然后将其写出。

 mysqldump -uroot -h my.host -p'mypassword' --quick --max_allowed_packet=512M db_name table_name | \
 gzip  > dump_test.sql.gz

您也可以尝试将 --compress 选项添加到您的 mysqldump 命令。这使得它使用更网络友好的压缩连接协议到您的 MySQL 服务器。请注意,您仍然需要 gzip 管道; MySQL 的压缩协议不会导致转储从 mysqldump 压缩出来。

服务器与 mysqldump 客户端的连接也可能超时。您可以尝试重置超时持续时间。通过其他方式连接到您的服务器并发出这些查询,然后 运行 您的 mysqldump 工作。

这些将超时设置为一个日历日。

    SET GLOBAL wait_timeout=86400;
    SET GLOBAL interactive_timeout=86400;

最后,如果您的服务器距离您的机器很远(通过路由器和防火墙),某些东西可能会中断 mysqldump 的连接。一些劣质路由器和防火墙对 NAT(网络地址转换)会话有时间限制。他们应该在使用时让这些会话保持活动状态,但有些则不然。或者,您可能正在达到公司为外部连接配置的时间或大小限制。

尝试登录到离服务器较近的机器并运行在其上mysqldump。 然后使用其他方式(sftp?)将您的 gz 文件复制到您自己的机器上。

或者,您可能需要对该文件的转储进行分段。您可以这样做(未调试)。

mysqldump  -uroot -h my.host -p'mypassword'  \ 
          db_name table_name --skip-create-options --skip-add-drop-table \
          --where="id>=0 AND id < 1000000" | \
          gzip....

然后用这些行重复。

          --where="id>=1000000 AND id < 2000000" | \

          --where="id>=2000000 AND id < 3000000" | \
          ...

直到您获得所有行。脖子痛,但它会起作用。

使用上面的 JohnBigs 评论,--compress 标志对我有用。

我之前尝试过 --single-transaction--skip-extended-insert--quick w/o 成功。

要尝试的其他选项:

net_read_timeout=3600 
net_write_timeout=3600

在我的.ini/my.cnf 或通过 SET GLOBAL ...

对我来说,当我跳过锁表时一切正常

 mysqldump -u xxxxx --password=xxxxx --quick --max_allowed_packet=512M --skip-lock-tables --verbose   -h xxx.xxx.xxx.xxx > db.sql

我可能会产生一致性问题,但允许我毫无问题地备份 5GB 数据库。

我的服务器上也有类似的问题,MySQL 显然会在夜间备份期间重新启动。它始终是相同的数据库,但实际 table 有时会有所不同。

在这里尝试了其他答案中的几个,但最终只是一些 cronjob 执行的查询没有完成。这并没有导致触发监控的 CPU 和 RAM 使用量,但显然足够压缩转储导致 OOM 杀手变得活跃。修复了cronjob,下次备份又ok了。

要寻找的东西:

  • 哎呀? dmesg | grep invoked
  • 进程被终止? grep killed /var/log/kern.log

此外,请确保您的 MYSQL.EXE 客户端与 mysql 服务器的版本相同。

因此,如果您 mysql 的版本是 8.0.23,但您的客户端版本是 8.0.17 或 8.0.25,您可能会遇到问题。我 运行 在 mysql 服务器 8.0.23 上使用版本 8.0.17 解决了这个问题 - 更改客户端版本以匹配服务器版本解决了这个问题。