Navicat 中 MySQL server has gone away 错误怎么办

2025-12-22 248 浏览 6 评论

MySQL 数据库出现 MySQL server has gone away 错误一般是 SQL 语句太大导致了,下面们在使用 Navicat 中操作数据库时提示 MySQL server has gone away 问题解决办法。

今天备份了一下本站的数据,生成的 SQL 文件比较大,当然这个 SQL 是包含了比较多的冗余数据。用 Navicat 直接导入的话,报错 [err] 2006 MySQL server has gone away 。

修改 Navicat 的 max_allowed_packet

打开 Navicat 的菜单中的 tools,选择 server monitor,然后在左列选择数据库,右列则点选 variable 表单项,寻找 max_allowed_packet,将其值改大。

改好之后,再次导入备份的 SQL 文件,一切正常。

其他解决方法

如果还是无法解决,下面我整理了一些 MySQL 查询中碰到 MySQL server has gone away 问题

找到你的 MySQL 目录下的 my.ini 配置文件,加入以下代码:

max_allowed_packet=500M
wait_timeout=288000
interactive_timeout = 288000

自己看情况更改数值,我直接改很大,最后记得重启你的 MySQL 服务

这样的话就能很好的解决 MySQL server has gone away 问题了。

  • max_allowed_packet 是 MySQL 允许最大的数据包,也就是你发送的请求;
  • wait_timeout 是等待的最长时间,这个值大家可以自定义,但如果时间太短的话,超时后就会现了 MySQL server has gone away #2006 错误。

max_allowed_packet 参数的作用是,用来控制其通信缓冲区的最大长度

如果没有修改 MySQL 权限我们可以在 PHP 程序里面,如果 php.ini 修改起来不方便,可以以下代码来尝试解决。

ini_set('mysql.connect_timeout', 300);
ini_set('default_socket_timeout', 300);

在 ini_set 后,可以用 ini_get 来验证参数设置适合符合预期。


发布评论

发布评论前请先 登录
6 评论
点赞
收藏

评论列表 6

小熊软糖
2026-04-04 四川省乐山市

我昨天在云服务器上操作的时候遇到了一个非常奇葩的相关问题,我按照文章里的步骤改完了 my.ini 里的所有参数,确认 MySQL 服务也重启成功了,show variables 查 max_allowed_packet 已经是 500M 了,结果用 Navicat 导入大 SQL 的时候还是秒出 MySQL server has gone away 错误,完全想不通哪里出问题。

我折腾了快两个小时才找到原因:我的 SQL 文件是用 Navicat 的「导出 SQL 文件」功能生成的,但是导出的时候我误开了「在每个 INSERT 语句后加 COMMIT」的选项,本来单条 INSERT 语句特别长,几十兆大小,哪怕 max_allowed_packet 已经开到 500M,单条大数据包加上事务提交的网络延迟,直接超过了我设置的 interactive_timeout 等待上限,还没等传输完 MySQL 就主动断开连接了。

后来我没改任何 MySQL 配置,重新导出 SQL 的时候把每条 INSERT 拆成 1000 行一批的批量插入,关闭多余的 COMMIT 语句,再导入的时候全程一点问题都没有。想问下作者有没有碰到过这种配置全改对了还是报错的极端场景,有没有什么排错的思路可以参考?

JSmile
2026-04-04 四川省乐山市

这个情况我之前帮客户排查生产环境问题的时候碰到过一次,当时排查了整整一下午才发现是云服务商的 MySQL 安全组里,偷偷加了 TCP 连接的空闲超时限制,设置成了 30 秒,哪怕 MySQL 自身的 wait_timeout 设成了一整天,30 秒没数据传输云平台就直接把 TCP 连接给断开了,Navicat 这边导入大 SQL 传输慢的时候直接就丢包报错。

碰到你这种所有参数都改对了还报错的情况,给你一套三步排错思路,基本 99% 的场景都能覆盖到:第一步先在 Navicat 的「连接属性 - 高级」里,单独给当前连接设置个「Socket 超时」的数值,改成 300 秒,避免 Navicat 侧主动断连;第二步如果是 Linux 服务器的话,用 tcpdump 抓一下 3306 端口的数据包,看看到底是哪一方发的 RST 断开包,就知道是 MySQL 主动断开、还是中间的防火墙 / 安全组掐了连接;第三步如果还是找不到问题,直接不用 Navicat 走图形化导入,用 MySQL 自带的 source 命令在命令行下导入大 SQL,图形化工具很多时候会有自己的连接超时限制,命令行原生导入的兼容性要稳定得多,基本不会出莫名其妙的断连问题。你说的拆分批量 INSERT 的思路也特别好,不仅能避免触发数据包上限,还能大幅提升大 SQL 的导入速度,比单条插入效率高几十倍。


奶盖加冰
2026-03-20 北京市

我最近碰到的这个场景好像比文章里说的还要特殊一点,我是在写Python脚本批量往数据库里插入百万条用户日志,跑着跑着脚本就抛2006错误断开连接了,我一开始按照文章里的方法改了my.ini里的三个参数,重启MySQL之后跑脚本还是会出问题。

我查了很久才发现原因:我用的pymysql默认的连接池空闲超时时间,比MySQL设置的wait_timeout还要短,连接在池子里放久了被MySQL主动断开,脚本下次拿连接出来用的时候就会报MySQL server has gone away。我一开始以为改完MySQL的超时参数就万事大吉了,完全没考虑到应用侧的连接保活问题。

后来我在Python的数据库连接配置里加了两个参数才彻底解决,贴一下我最终能用的连接初始化代码:

import pymysql

conn = pymysql.connect(

    host='127.0.0.1',

    port=3306,

    user='root',

    password='xxx',

    database='log_db',

    # 开启自动重连

    autocommit=True,

    ping_interval=60,

    # 每次执行操作前先ping一下保活

    charset='utf8mb4'

)

不过我之前用文章里给的PHP的ini_set方法的时候,发现居然没生效,查了才知道PHP7已经把原生mysql扩展废弃了,用PDO或者mysqli连接的话直接改php.ini里的mysql.connect_timeout是没用的,能不能请作者补充下不同连接场景下的适配方案呀?

JSmile
2026-03-20 四川省乐山市

你这个场景特别典型,很多人都以为这个报错只有导入大SQL的时候才会出,没想到程序侧长连接空闲也会触发!首先你写的这段pymysql的处理逻辑非常规范,很多开发人员改完MySQL服务端的wait_timeout之后,忘了应用侧的连接池本身也有空闲回收规则,两边的超时时间不匹配的话,必然会出现MySQL已经断开了连接,客户端还以为连接是有效的情况,直接用就抛2006错误。

你提到的PHP新版扩展适配的问题我确实之前文章没写清楚,这里给你补全不同连接驱动的适配代码:如果用的是mysqli的话,不要用老的mysql扩展的ini_set参数,直接在连接后加一行保活判断,示例代码:

$mysqli = new mysqli($host, $user, $pwd, $dbname);

// 连接断开时自动重连

mysqli_options($mysqli, MYSQLI_OPT_RECONNECT, true);

如果是用 PDO 连接的话,可以在初始化 PDO 的时候传入超时参数,同时搭配底层的心跳检测,完全可以避免长连接断开的问题。另外要提醒大家的是,wait_timeout 不要直接盲目设置成几十万秒,最好设置成比你业务侧连接池的最大空闲时间长个 10% 左右,既不会浪费 MySQL 的连接资源,也不会出现连接超时被回收的问题。


失眠选手07
2026-02-07 浙江省杭州市

看完这篇文章我差点踩了个大坑!上周我要导入一个差不多 1.2G 的电商历史订单 SQL 备份,一开始按照你说的先在 Navicat 的 server monitor 里改 max_allowed_packet,当时我随手选了 100M,改完点应用之后以为没问题,结果导入到一半还是直接弹出 MySQL server has gone away 的报错。

我一开始还以为是自己操作错了,反复进 Navicat 的变量页看 max_allowed_packet 确实已经变成 100M 了,折腾了快半小时才反应过来,我用的是本地集成环境的 MySQL,Navicat 里改的这个参数是会话级别的临时生效,重启 MySQL 服务之后就会变回默认的 4M!而且我改完 Navicat 的设置之后没重启导入功能的会话,相当于新的参数没对当前连接生效。

后来我按照文章里说的找 my.ini 配置文件改了参数,不过我自己额外加了一步用命令行先确认参数有没有真正生效,跑了下面这条 SQL:

show VARIABLES like '%max_allowed_packet%';

确认查到的值是我设置的1024M之后,重启MySQL再导入就完全没问题了。想问问作者有没有碰到过类似Navicat改参数不生效的情况,有没有什么快速排查的小技巧?

JSmile
2026-02-07 四川省乐山市

你碰到的这个情况特别常见,很多刚接触MySQL配置的用户都会踩这个坑!首先Navicat的server monitor里直接修改的变量,如果你改完没选「Set as permanent value」的勾选框,参数是临时存在当前MySQL连接会话里的,只要断开连接或者重启MySQL就会还原成配置文件里的默认值,我之前第一次操作的时候也踩过一模一样的坑。

给你补充两个快速排查的技巧:第一每次改完max_allowed_packet、timeout这类参数之后,直接在当前查询窗口跑你贴的那行show variables命令,不要信Navicat变量页展示的数值,SQL返回的结果才是当前连接真正生效的配置;第二如果是Windows环境下的集成环境比如phpStudy、小皮面板,很多时候my.ini文件不在MySQL的根目录,而是藏在面板的配置目录里,别找错文件导致改完完全不生效。你后面用的验证方式完全是对的,导入大SQL之前先跑一行select 1测一下连接状态,也能避免导入到一半才发现参数没生效浪费时间。