error 2006 表示连接未断开但服务器已关闭,主因是 wait_timeout 和 interactive_timeout 超时(默认8小时),其次为 max_allowed_packet 过小导致大数据包被截断。

2006 错误就是客户端突然发现“连不上 MySQL 了”,不是网络彻底断开,而是连接还挂着,但服务器端已经把它关掉了——你发一条 SELECT,它回你一句 ERROR 2006 (HY000): MySQL server has gone away。
为什么 wait_timeout 和 interactive_timeout 是头号嫌疑?
MySQL 默认 8 小时(wait_timeout=28800)没动静就杀连接。PHP 长脚本、Python 的 time.sleep() 后续再查库、Java 连接池里闲置的连接,都容易撞上这个点。
- 查当前值:
SHOW GLOBAL VARIABLES LIKE '%timeout%';,重点关注wait_timeout和interactive_timeout - 临时调高(仅本次会话生效):
SET SESSION wait_timeout = 3600;;全局改用SET GLOBAL wait_timeout = 3600;(需 SUPER 权限) - 永久生效必须改配置文件:在
[mysqld]段下加wait_timeout = 3600和interactive_timeout = 3600,改完必须sudo systemctl restart mysql - ⚠️ 注意:
interactive_timeout控制的是带--interactive标志的客户端(比如你手动敲mysql -u root -p),而程序里大多数连接走的是wait_timeout
max_allowed_packet 太小,大 SQL 或 BLOB 直接被截断
不是“慢”,是“发不过去”。比如导一个含长文本或图片字段的 SQL 文件,或者 Python 用 executemany() 一次性插几千行,超出限制就会报 2006,且日志里往往没明显错误。
- 查当前上限:
SELECT @@max_allowed_packet;(单位字节),常见默认是 4MB 或 16MB - 导入前临时加大:
mysql --max-allowed-packet=512M -u root -p db_name - 永久设置:在
[mysqld]下加max_allowed_packet = 512M,重启服务;别写在 [mysql] 段里,那只是客户端默认值,不影响服务端校验 - 应用层补救:Python 的
pymysql可传max_allowed_packet=536870912参数;Node.js 的mysql2用maxPacketSize: 536870912
别漏掉客户端和中间件的超时联动
只调 MySQL 的 wait_timeout 不够——如果 PHP 的 mysql.connect_timeout 是 30 秒,或连接池(如 HikariCP)的 connection-timeout 是 30s,它早就在 MySQL 关连接前主动断开了,但错误可能仍表现为 2006。
- PHP:检查
php.ini中mysql.connect_timeout和mysqli.reconnect = On(自动重连,慎用) - Python:用
pymysql时加autocommit=True+ping(True)手动保活;SQLAlchemy 可配pool_pre_ping=True - Docker/K8s 场景:Nginx 或 Service Mesh 的 idle timeout(如 Istio 默认 1h)也可能比 MySQL 更早切断连接
真正难排查的,往往是多个超时层层嵌套:客户端等 30 秒连不上,MySQL 等 8 小时才关连接,而中间代理又卡在 5 分钟。先确认是哪一层先动手的,比盲目调大所有 timeout 更有效。










