本节还介绍了相关的 查询期间与服务器断开连接
错误。
出现 MySQL 服务器已断开连接
错误的最常见原因是服务器超时并关闭了连接。在这种情况下,通常会收到以下错误代码之一(收到哪个代码取决于操作系统)。
错误代码 | 描述 |
---|---|
CR_SERVER_GONE_ERROR |
客户端无法将问题发送到服务器。 |
CR_SERVER_LOST |
客户端在写入服务器时未收到错误,但未收到完整答案(或任何答案)以回答问题。 |
默认情况下,如果服务器八小时内未发生任何操作,它将关闭连接。可以通过在启动 mysqld 时设置 wait_timeout
变量来更改超时限制。请参阅 第 7.1.8 节,“服务器系统变量”。
如果您有一个脚本,您只需要再次发出查询,客户端就会自动重新连接。这假设您已在客户端中启用自动重新连接(这是 mysql
命令行客户端的默认设置)。
导致出现 MySQL 服务器已断开连接
错误的其他一些常见原因是
您(或数据库管理员)已使用
KILL
语句或 mysqladmin kill 命令终止了正在运行的线程。您尝试在关闭与服务器的连接后运行查询。这表明应用程序中存在逻辑错误,应予以更正。
在不同主机上运行的客户端应用程序没有从该主机连接到 MySQL 服务器所需的权限。
您从客户端的 TCP/IP 连接中超时。如果您使用了以下命令,则可能会发生这种情况:
mysql_options(..., MYSQL_OPT_READ_TIMEOUT,...)
或mysql_options(..., MYSQL_OPT_WRITE_TIMEOUT,...)
。在这种情况下,增加超时时间可能有助于解决问题。您在服务器端遇到了超时,并且客户端的自动重新连接被禁用(
MYSQL
结构中的reconnect
标志等于 0)。您使用的是 Windows 客户端,并且服务器在发出命令之前已断开了连接(可能是因为
wait_timeout
过期)。Windows 上的问题是,在某些情况下,MySQL 在写入与服务器的 TCP/IP 连接时不会从操作系统收到错误,而是在尝试从连接中读取答案时才会收到错误。
解决此问题的办法是,如果距离上次查询已经很长时间,则在连接上执行
mysql_ping()
(这是 Connector/ODBC 的做法),或者在 mysqld 服务器上设置wait_timeout
为如此高的值,以至于实际上永远不会超时。如果您将不正确或过大的查询发送到服务器,也可能会收到这些错误。如果 mysqld 收到过大的数据包或顺序错误的数据包,它会认为客户端出现错误并关闭连接。如果您需要大型查询(例如,如果您正在使用大型
BLOB
列),您可以通过设置服务器的max_allowed_packet
变量来增加查询限制,该变量的默认值为 64MB。您可能还需要增加客户端端的最大数据包大小。有关设置数据包大小的更多信息,请参阅 第 B.3.2.8 节,“数据包太大”。插入大量行的
INSERT
或REPLACE
语句也可能会导致此类错误。无论要插入多少行,这两个语句都只向服务器发送一个请求;因此,通常可以通过减少每次INSERT
或REPLACE
发送的行数来避免错误。如果主机名查找失败(例如,如果您服务器或网络所依赖的 DNS 服务器出现故障),也可能会看到此错误。这是因为 MySQL 依赖主机系统进行名称解析,但无法知道它是否正常工作——从 MySQL 的角度来看,这个问题与任何其他网络超时没有区别。
如果 MySQL 以启用了
skip_networking
系统变量的方式启动,也可能会看到MySQL 服务器已断开连接
错误。另一个可能导致此错误的网络问题是,如果您的防火墙阻止了 MySQL 端口(默认端口为 3306),从而完全阻止了与 MySQL 服务器的任何连接。
使用分支子进程的应用程序也可能会遇到此错误,所有这些子进程都尝试使用相同的连接到 MySQL 服务器。可以通过为每个子进程使用单独的连接来避免这种情况。
您遇到了服务器在执行查询时崩溃的错误。
您可以通过执行 mysqladmin version 并检查服务器的运行时间来查看 MySQL 服务器是否已崩溃并重新启动。如果客户端连接中断是因为 mysqld 崩溃并重新启动,则应集中查找崩溃原因。首先检查再次发出查询是否会再次终止服务器。请参阅 第 B.3.3.3 节,“如果 MySQL 持续崩溃该怎么办”。
您可以通过在 log_error_verbosity
系统变量设置为 3 的情况下启动 mysqld 来获取有关连接丢失的更多信息。这将在 hostname.err
文件中记录一些断开连接消息。请参阅 第 7.4.2 节,“错误日志”。
如果您要创建有关此问题的错误报告,请确保包含以下信息
说明 MySQL 服务器是否已崩溃。您可以在服务器错误日志中找到有关此信息。请参阅 第 B.3.3.3 节,“如果 MySQL 持续崩溃该怎么办”。
如果某个特定查询导致 mysqld 崩溃,并且您在运行该查询之前使用
CHECK TABLE
检查了相关的表格,您能提供一个可重现的测试用例吗?请参阅 第 7.9 节,“调试 MySQL”。MySQL 服务器中
wait_timeout
系统变量的值是多少? (mysqladmin variables 会显示此变量的值。)您是否尝试过启用通用查询日志运行 mysqld,以确定问题查询是否出现在日志中? (请参阅 第 7.4.3 节,“通用查询日志”。)