B.3.2.7 MySQL 服务器已断开连接
本节还涵盖了相关的Lost connection to server during query
错误。
MySQL 服务器已断开连接的最常见原因是服务器超时关闭连接。在这种情况下,您通常会收到以下错误代码(具体哪一个取决于操作系统)。
Error Code | Description |
---|---|
CR_SERVER_GONE_ERROR |
客户端无法将问题发送到服务器。 |
CR_SERVER_LOST |
客户端在写入服务器时没有收到错误,但也没有收到完整的回答(或任何回答)。 |
默认情况下,服务器将在八小时内关闭连接,如果没有发生任何事情。您可以通过设置wait_timeout
变量来更改超时限制,当您启动mysqld时。请参阅第7.1.8节,“服务器系统变量”。
如果您有脚本,只需重新发送查询,以便客户端自动重新连接。这假设了在客户端中启用了自动重新连接(默认情况下为命令行客户端mysql
)。
一些其他常见的原因是:
-
您(或数据库管理员)使用了
KILL
语句或mysqladmin kill命令杀死了正在运行的线程。 -
您尝试在关闭服务器连接后运行查询。这表明应用程序中存在逻辑错误,需要被纠正。
-
来自不同主机的客户端应用程序没有必要的权限来从该主机连接到 MySQL 服务器。
-
您在客户端侧遇到了 TCP/IP 连接超时。这可能是因为您使用了以下命令:
mysql_options(..., MYSQL_OPT_READ_TIMEOUT,...)
或mysql_options(..., MYSQL_OPT_WRITE_TIMEOUT,...)
。在这种情况下,增加超时时间可能会帮助解决问题。 -
您在服务器侧遇到了超时,并且客户端的自动重新连接功能被禁用(
reconnect
标志在MYSQL
结构中等于 0)。 -
您使用的是 Windows 客户端,服务器已经断开了连接(可能是因为
wait_timeout
超时)之前命令被发出。在 Windows 中,MySQL 在写入 TCP/IP 连接到服务器时,不会总是从操作系统获取错误,而是在尝试从连接中读取答案时获取错误。
解决这个问题的方法之一是,如果自上次查询以来已经过了很长时间,就在连接上执行
mysql_ping()
(Connector/ODBC 就是这样做的),或者将wait_timeout
在mysqld服务器上设置得足够高,以至于实际上从不超时。 -
你也可以在发送给服务器的查询语句中出现错误或太大时获取这些错误。如果mysqld接收到一个太大的或不正确的数据包,它将假设客户端出现了问题并关闭连接。如果你需要发送大型查询语句(例如,如果你正在处理大型
BLOB
列),你可以通过设置服务器的max_allowed_packet
变量来增加查询限制,该变量默认值为 64MB。你可能还需要在客户端上增加最大数据包大小。关于设置数据包大小的更多信息,请参阅第 B.3.2.8 节,“Packet Too Large”。INSERT
或REPLACE
语句插入大量行也可能会导致这些错误。无论是这两个语句,它们都会将单个请求发送到服务器,而不考虑要插入的行数;因此,您可以通过减少每个INSERT
或REPLACE
语句中的行数来避免错误。 -
您还可能会看到这个错误,如果主机名解析失败(例如,如果您的服务器或网络依赖的 DNS 服务器崩溃)。这是因为 MySQL 依赖于主机系统进行名称解析,但没有办法知道是否工作——从 MySQL 的角度来看,这个问题与任何其他网络超时问题无异。
您也可能会看到
MySQL 服务器已经关闭
错误,如果 MySQL 使用了skip_ networking
系统变量启动。另一个网络问题可能会导致这个错误,即 MySQL 端口(默认 3306)被防火墙阻止,从而阻止了对 MySQL 服务器的所有连接。
-
您也可以在应用程序中遇到这个错误,这些应用程序将 fork 子进程,每个子进程都尝试使用同一个连接来访问 MySQL 服务器。这可以通过为每个子进程使用单独的连接来避免。
-
您已经遇到了一个bug,服务器在执行查询时崩溃了。
您可以通过执行mysqladmin version并检查服务器的 uptime来确定MySQL服务器是否崩溃重启。如果客户端连接因mysqld崩溃重启而中断,您应该集中精力找到崩溃的原因。首先,检查是否重新执行查询会导致服务器崩溃。请参阅第 B.3.3.3 节,“如果 MySQL 总是崩溃”。
您可以通过将mysqld启动时设置log_error_verbosity
系统变量为 3,以便在hostname.err文件中记录一些断开连接的消息。请参阅第 7.4.2 节,“错误日志”。
如果您想报告这个问题,请确保包括以下信息:
-
指明 MySQL 服务器是否崩溃。您可以在服务器错误日志中找到相关信息。请参阅第 B.3.3.3 节,“如果 MySQL 总是崩溃”。
-
如果特定的查询杀死了mysqld,并且参与的表在运行查询前已经使用
CHECK TABLE
进行检查,可以提供可重复测试用例?请见第7.9节,“Debugging MySQL”。 -
MySQL 服务器中的
wait_timeout
系统变量的值是多少?(mysqladmin variables可以提供该变量的值。) -
您已经尝试使用mysqld启用一般查询日志,以确定问题查询是否出现在日志中?(请见第7.4.3节,“The General Query Log”。)
请见第B.3.2.9节,“Communication Errors and Aborted Connections”和第1.6节,“How to Report Bugs or Problems”。