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
目录。 (数据目录通常名为data
或var
,位于 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 端程序,也必须在服务器主机的user
table 行中指定主机名。
-
Access denied
错误消息告诉您您要尝试登录的用户,您要尝试与其连接的 Client 端主机以及是否正在使用密码。通常,在user
table 中应该有一行与错误消息中给出的主机名和用户名完全匹配。例如,如果收到包含using password: NO
的错误消息,则 table 示您尝试不使用密码登录。 -
如果尝试使用
mysql -u user_name
连接到数据库时出现Access denied
错误,则user
table 可能存在问题。通过执行mysql -u root mysql
并发出以下 SQL 语句进行检查:
SELECT * FROM user;
结果中应包含一行,其中Host
和User
列与 Client 端的主机名和 MySQL 用户名匹配。
- 如果当您尝试从运行 MySQL 服务器的主机之外的主机进行连接时发生以下错误,则意味着
user
table 中没有与 Client 端主机匹配的Host
值的行:
Host ... is not allowed to connect to this MySQL server
您可以通过为尝试连接时使用的 Client 端主机名和用户名的组合设置一个帐户来解决此问题。
如果您不知道要连接的计算机的 IP 地址或主机名,则应在user
table 中放入带有'%'
作为Host
列值的行。尝试从 Client 端计算机连接后,使用SELECT USER()
查询查看您实际如何连接。然后,将user
table 行中的'%'
更改为日志中显示的实际主机名。否则,您的系统将处于不安全状态,因为它允许来自任何主机的给定用户名的连接。
在 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
的身份连接并出现以下错误,则意味着user
table 中没有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 的实际主机名),则在user
table 中您的主机名可能不正确。此处的一个常见问题是user
table 行中的Host
值指定了不合格的主机名,但是系统的名称解析例程返回了完全合格的域名(反之亦然)。例如,如果在user
table 中有一个主机为'pluto'
的行,但是您的 DNS 告诉 MySQL 您的主机名是'pluto.example.com'
,则该行不起作用。尝试在user
table 中添加一行,该行包含主机的 IP 地址作为Host
列值。 (或者,您可以将Host
值添加到user
table 中,该值包含通配符(例如'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
,请从user
table 中删除所有具有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
消息,则user
table 中的行未启用FILE特权。 -
如果直接更改授予 table(例如,使用INSERT,UPDATE或DELETE语句),而您的更改似乎被忽略,请记住,必须执行FLUSH PRIVILEGES语句或mysqladmin flush-privileges命令才能使服务器重新加载特权 table。否则,您的更改将在下一次重新启动服务器之前不起作用。请记住,使用UPDATE语句更改
root
密码后,直到刷新权限后才需要指定新密码,因为服务器尚不知道您已更改密码! -
如果您的特权在会话过程中似乎已更改,则可能是 MySQLManagement 员已更改了它们。重新加载授权 table 会影响新的 Client 端连接,但也会影响现有的连接,如第 6.2.9 节“特权更改何时生效”所示。
-
如果您在使用 Perl,PHP,Python 或 ODBC 程序时遇到访问问题,请尝试使用
mysql -u user_name db_name
或mysql -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。