6.2.17 对连接到 MySQL 的问题进行故障排除

如果在尝试连接到 MySQL 服务器时遇到问题,则以下各项描述了一些可用于纠正问题的操作。

  • 确保服务器正在运行。如果不是,则 Client 端无法连接到它。例如,如果尝试连接服务器失败,并显示以下消息之一,则可能是服务器未运行:
shell> mysql
ERROR 2003: Can't connect to MySQL server on 'host_name' (111)
shell> mysql
ERROR 2002: Can't connect to local MySQL server through socket
'/tmp/mysql.sock' (111)
  • 可能是服务器正在运行,但是您尝试使用与服务器侦听的端口不同的 TCP/IP 端口,命名管道或 Unix 套接字文件进行连接。要在调用 Client 端程序时更正此问题,请指定--port选项以指示正确的端口号,或指定--socket选项以指示正确的命名管道或 Unix 套接字文件。要找出套接字文件在哪里,可以使用以下命令:
shell> netstat -ln | grep mysql
  • 确保未将服务器配置为忽略网络连接,或者(如果您尝试远程连接)未将服务器配置为仅在其网络接口上本地侦听。如果服务器是在启用skip_networking系统变量的情况下启动的,则它将完全不接受 TCP/IP 连接。如果服务器是在bind_address系统变量设置为127.0.0.1的情况下启动的,则它将仅在回送接口上本地侦听 TCP/IP 连接,并且不接受远程连接。

  • 检查以确保没有防火墙阻止对 MySQL 的访问。您的防火墙可以根据正在执行的应用程序或 MySQL 用于通信的端口号进行配置(默认为 3306)。在 Linux 或 Unix 下,检查 IPtable(或类似的配置)以确保端口未被阻塞。在 Windows 下,可能需要配置诸如 ZoneAlarm 或 Windows 防火墙之类的应用程序,以不阻止 MySQL 端口。

  • 必须正确设置授权 table,以便服务器可以将它们用于访问控制。对于某些分发类型(例如 Windows 上的二进制分发或 Linux 上的 RPM 和 DEB 分发),安装过程将初始化 MySQL 数据目录,包括包含授权 table 的mysql系统数据库。对于不执行此操作的发行版,必须手动初始化数据目录。有关详细信息,请参见第 2.10 节“安装后的设置和测试”

要确定是否需要初始化授权 table,请在数据目录下查找mysql目录。 (数据目录通常名为datavar,位于 MySQL 安装目录下.)确保mysql数据库目录中有一个名为user.MYD的文件。如果不是,则为初始化数据目录。这样做并启动服务器后,您应该能够连接到服务器。

  • 全新安装后,如果尝试不使用密码以root身份登录服务器,则可能会收到以下错误消息。
shell> mysql -u root 
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

这意味着在安装过程中已经分配了 root 密码,并且必须提供该密码。有关分配密码的不同方式以及在某些情况下如何查找密码的信息,请参见第 2.10.4 节“保护初始 MySQL 帐户”。如果您需要重置 root 密码,请参阅B.4.3.2 节,“如何重设根密码”中的说明。找到或重置密码后,使用--password(或-p)选项再次以root身份登录:

shell> mysql -u root -p
Enter password:

但是,如果您已使用mysqld --initialize-insecure初始化 MySQL,则服务器将允许您以root的身份进行连接而无需使用密码(有关详细信息,请参见第 2.10.1 节“初始化数据目录”)。这是安全隐患,因此您应该为root帐户设置密码。有关说明,请参见第 2.10.4 节“保护初始 MySQL 帐户”

  • 如果您已将现有的 MySQL 安装更新为较新的版本,是否执行了 MySQL 升级过程?如果没有,请这样做。添加新功能后,授权 table 的结构有时会发生变化,因此在升级之后,您应始终确保 table 具有当前结构。有关说明,请参见第 2.11 节“升级 MySQL”

  • 如果 Client 端程序在尝试连接时收到以下错误消息,则 table 示服务器希望使用比 Client 端能够生成的格式新的密码:

shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client

有关如何处理此问题的信息,请参见第 6.4.1.3 节“迁移到 4.1 版之前的密码哈希和 mysql_old_password 插件”

  • 请记住,Client 端程序使用在选项文件或环境变量中指定的连接参数。如果您未在命令行上指定 Client 端程序时似乎在发送不正确的默认连接参数,请检查所有适用的选项文件和您的环境。例如,如果在运行没有任何选项的 Client 端时得到Access denied,请确保未在任何选项文件中指定旧密码!

您可以通过使用--no-defaults选项调用 Client 端程序来禁止使用选项文件。例如:

shell> mysqladmin --no-defaults -u root version

第 4.2.2.2 节“使用选项文件”中列出了 Client 端使用的选项文件。环境变量在第 4.9 节“环境变量”中列出。

  • 如果收到以下错误,则 table 明您使用的是不正确的root密码:
shell> mysqladmin -u root -pxxxx ver
Access denied for user 'root'@'localhost' (using password: YES)

如果即使您没有指定密码也发生上述错误,则意味着您在某些选项文件中列出了错误的密码。请尝试上一项目中所述的--no-defaults选项。

有关更改密码的信息,请参见第 6.2.10 节“分配帐户密码”

如果您丢失或忘记了root密码,请参阅B.4.3.2 节,“如何重设根密码”

  • localhost是您的 localhost 名的同义词,如果您未明确指定主机,它也是 Client 端尝试连接的默认主机。

您可以使用--host=127.0.0.1选项来明确命名服务器主机。这将构建与本地mysqld服务器的 TCP/IP 连接。您还可以通过指定--host选项来使用 TCP/IP,该选项使用 localhost 的实际主机名。在这种情况下,即使您在与服务器相同的主机上运行 Client 端程序,也必须在服务器主机的usertable 行中指定主机名。

  • Access denied错误消息告诉您您要尝试登录的用户,您要尝试与其连接的 Client 端主机以及是否正在使用密码。通常,在usertable 中应该有一行与错误消息中给出的主机名和用户名完全匹配。例如,如果收到包含using password: NO的错误消息,则 table 示您尝试不使用密码登录。

  • 如果尝试使用mysql -u user_name连接到数据库时出现Access denied错误,则usertable 可能存在问题。通过执行mysql -u root mysql并发出以下 SQL 语句进行检查:

SELECT * FROM user;

结果中应包含一行,其中HostUser列与 Client 端的主机名和 MySQL 用户名匹配。

  • 如果当您尝试从运行 MySQL 服务器的主机之外的主机进行连接时发生以下错误,则意味着usertable 中没有与 Client 端主机匹配的Host值的行:
Host ... is not allowed to connect to this MySQL server

您可以通过为尝试连接时使用的 Client 端主机名和用户名的组合设置一个帐户来解决此问题。

如果您不知道要连接的计算机的 IP 地址或主机名,则应在usertable 中放入带有'%'作为Host列值的行。尝试从 Client 端计算机连接后,使用SELECT USER()查询查看您实际如何连接。然后,将usertable 行中的'%'更改为日志中显示的实际主机名。否则,您的系统将处于不安全状态,因为它允许来自任何主机的给定用户名的连接。

在 Linux 上,可能发生此错误的另一个原因是,您使用的是 MySQL 二进制版本,该版本是使用与所使用版本不同的glibc库版本编译的。在这种情况下,您应该升级 os 或glibc,或者下载 MySQL 版本的源分发版并自己进行编译。源 RPM 通常很难编译和安装,因此这不是一个大问题。

  • 如果您在尝试连接时指定了主机名,但收到一条错误消息,其中该主机名未显示或为 IP 地址,则 table 示 MySQL 服务器在尝试将 Client 端主机的 IP 地址解析为一个名字:
shell> mysqladmin -u root -pxxxx -h some_hostname ver
Access denied for user 'root'@'' (using password: YES)

如果您尝试以root的身份连接并出现以下错误,则意味着usertable 中没有User列值为'root'的行,并且mysqld无法解析 Client 端的主机名:

Access denied for user ''@'unknown'

这些错误 table 明 DNS 问题。要解决此问题,请执行mysqladmin flush-hosts以重置内部 DNS 主机缓存。参见第 5.1.11.2 节“ DNS 查找和主机缓存”

一些永久性的解决方案是:

  • 确定您的 DNS 服务器出了什么问题并进行修复。

    • 在 MySQL 授权 table 中指定 IP 地址而不是主机名。

    • 将 Client 端计算机名称的条目 ImportingUnix 上的/etc/hosts或 Windows 上的\windows\hosts

    • mysqld启用skip_name_resolve系统变量开始。

    • --skip-host-cache选项开始mysqld

    • 在 Unix 上,如果服务器和 Client 端在同一台计算机上运行,请连接到localhost。对于localhost的连接,除非指定了连接参数以确保 Client 端构建 TCP/IP 连接,否则 MySQL 程序会尝试使用 Unix 套接字文件连接到本地服务器。有关更多信息,请参见第 4.2.4 节“使用命令选项连接到 MySQL 服务器”

    • 在 Windows 上,如果服务器和 Client 端在同一台计算机上运行,并且服务器支持命名管道连接,请连接到主机名.(句点)。与.的连接使用命名管道而不是 TCP/IP。

  • 如果mysql -u root有效但mysql -h your_hostname -u root产生Access denied(其中* your_hostname 是 localhost 的实际主机名),则在usertable 中您的主机名可能不正确。此处的一个常见问题是usertable 行中的Host值指定了不合格的主机名,但是系统的名称解析例程返回了完全合格的域名(反之亦然)。例如,如果在usertable 中有一个主机为'pluto'的行,但是您的 DNS 告诉 MySQL 您的主机名是'pluto.example.com',则该行不起作用。尝试在usertable 中添加一行,该行包含主机的 IP 地址作为Host列值。 (或者,您可以将Host值添加到usertable 中,该值包含通配符(例如'pluto.%'.)但是,以%结尾的Host值的使用是不安全的*,并且不建议!)

  • 如果mysql -u user_name有效,但mysql -u user_name some_db无效,则您尚未授予名为* some_db *的数据库给定用户的访问权限。

  • 如果mysql -u user_name在服务器主机上执行时起作用,但是mysql -h host_name -u user_name在远程 Client 端主机上执行时不起作用,则您尚未从远程主机为给定的用户名启用对服务器的访问。

  • 如果无法弄清楚为什么得到Access denied,请从usertable 中删除所有具有Host值且包含通配符的行(包含'%''_'字符的行)。一个非常常见的错误是使用Host = '%'User = 'some_user'插入新行,认为这使您可以指定localhost从同一台计算机进行连接。之所以不起作用,是因为默认特权包括Host = 'localhost'User = ''的行。由于该行的Host'localhost''%'更具体,因此从localhost连接时,它优先于新行使用!正确的过程是插入Host = 'localhost'User = 'some_user'的第二行,或删除Host = 'localhost'User = ''的行。删除行后,请记住发出FLUSH PRIVILEGES语句以重新加载授权 table。另请参见第 6.2.5 节“访问控制,第 1 阶段:连接验证”

  • 如果您能够连接到 MySQL 服务器,但是在发出选择...进入外档LOAD DATA语句时收到Access denied消息,则usertable 中的行未启用FILE特权。

  • 如果直接更改授予 table(例如,使用INSERTUPDATEDELETE语句),而您的更改似乎被忽略,请记住,必须执行FLUSH PRIVILEGES语句或mysqladmin flush-privileges命令才能使服务器重新加载特权 table。否则,您的更改将在下一次重新启动服务器之前不起作用。请记住,使用UPDATE语句更改root密码后,直到刷新权限后才需要指定新密码,因为服务器尚不知道您已更改密码!

  • 如果您的特权在会话过程中似乎已更改,则可能是 MySQLManagement 员已更改了它们。重新加载授权 table 会影响新的 Client 端连接,但也会影响现有的连接,如第 6.2.9 节“特权更改何时生效”所示。

  • 如果您在使用 Perl,PHP,Python 或 ODBC 程序时遇到访问问题,请尝试使用mysql -u user_name db_namemysql -u user_name -ppassword db_name连接到服务器。如果您能够使用mysqlClient 端进行连接,则问题出在您的程序上,而不是访问权限上。 (-p和密码之间没有空格;您也可以使用--password=password语法来指定密码。如果您使用的-p--password选项没有密码值,则 MySQL 会提示您 Importing 密码。)

  • 为了进行测试,请使用--skip-grant-tables选项启动mysqld服务器。然后,您可以更改 MySQL 授权 table,并使用SHOW GRANTS语句检查您的修改是否具有所需的效果。对更改满意后,执行mysqladmin flush-privileges告诉mysqld服务器重新加载特权。这样,您就可以开始使用新的授权 table 内容,而无需停止和重新启动服务器。

  • 如果其他所有操作均失败,请使用调试选项(例如--debug=d,general,query)启动mysqld服务器。这将打印有关尝试连接的主机和用户信息,以及有关发出的每个命令的信息。参见第 28.5.3 节“ DBUG 软件包”

  • 如果您对 MySQL 授权 table 有任何其他问题,并在MySQL 社区松弛上询问,请始终提供 MySQL 授权 table 的转储。您可以使用mysqldump mysql命令转储 table。要提交错误报告,请参见第 1.7 节“如何报告错误或问题”上的说明。在某些情况下,您可能需要使用--skip-grant-tables重新启动mysqld才能运行mysqldump