如果您在尝试连接到 MySQL 服务器时遇到问题,以下内容描述了一些可以采取的措施来纠正问题。
确保服务器正在运行。如果没有,客户端无法连接到它。例如,如果尝试连接到服务器失败,并出现以下消息之一,则原因可能是服务器没有运行。
$> mysql ERROR 2003: Can't connect to MySQL server on 'host_name' (111) $> mysql ERROR 2002: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)
服务器可能正在运行,但您正在尝试使用不同的 TCP/IP 端口、命名管道或 Unix 套接字文件来连接,而服务器正在监听该端口、管道或文件。要更正这种情况,在调用客户端程序时,指定
--port
选项来指示正确的端口号,或指定--socket
选项来指示正确的命名管道或 Unix 套接字文件。要找出套接字文件的位置,可以使用以下命令。$> netstat -ln | grep mysql
确保服务器没有被配置为忽略网络连接,或者(如果尝试远程连接)确保服务器没有被配置为仅在其网络接口上本地监听。如果服务器启动时启用了
skip_networking
系统变量,则不接受任何 TCP/IP 连接。如果服务器启动时将bind_address
系统变量设置为127.0.0.1
,则它仅在环回接口上本地监听 TCP/IP 连接,并且不接受远程连接。检查以确保没有防火墙阻止对 MySQL 的访问。您的防火墙可能会根据正在执行的应用程序或 MySQL 用于通信的端口号(默认情况下为 3306)进行配置。在 Linux 或 Unix 下,检查您的 IP 表(或类似配置)以确保端口没有被阻止。在 Windows 下,ZoneAlarm 或 Windows 防火墙等应用程序可能需要进行配置以不阻止 MySQL 端口。
授权表必须正确设置,以便服务器可以使用它们进行访问控制。对于某些发行版类型(例如 Windows 上的二进制发行版或 Linux 上的 RPM 和 DEB 发行版),安装过程会初始化 MySQL 数据目录,包括包含授权表的
mysql
系统数据库。对于不执行此操作的发行版,您必须手动初始化数据目录。有关详细信息,请参阅 第 2.9 节,“安装后设置和测试”。要确定是否需要初始化授权表,请在数据目录下查找
mysql
目录。(数据目录通常名为data
或var
,并且位于您的 MySQL 安装目录下。)确保在mysql
数据库目录下有一个名为user.MYD
的文件。如果没有,请初始化数据目录。执行此操作并启动服务器后,您应该能够连接到服务器。在全新安装后,如果您尝试以
root
身份登录服务器,而没有使用密码,则可能会收到以下错误消息。$> mysql -u root ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
这意味着在安装期间已分配了 root 密码,并且必须提供它。 请参阅 第 2.9.4 节,“保护初始 MySQL 帐户”,了解密码分配的不同方式,以及在某些情况下如何找到它。 如果您需要重置 root 密码,请参阅 第 B.3.3.2 节,“如何重置 root 密码” 中的说明。 找到或重置密码后,请使用
--password
(或-p
)选项以root
身份再次登录。$> mysql -u root -p Enter password:
但是,如果您使用 mysqld --initialize-insecure 初始化了 MySQL(有关详细信息,请参阅 第 2.9.1 节,“初始化数据目录”),则服务器将允许您以
root
身份连接而无需使用密码。 这存在安全风险,因此您应该为root
帐户设置密码; 请参阅 第 2.9.4 节,“保护初始 MySQL 帐户” 以获取说明。如果您已将现有 MySQL 安装更新到较新版本,您是否执行了 MySQL 升级过程? 如果没有,请执行此操作。 当添加新功能时,授予表的结构偶尔会发生变化,因此在升级后,您应该始终确保您的表具有当前结构。 有关说明,请参阅 第 3 章,升级 MySQL。
如果客户端程序在尝试连接时收到以下错误消息,则意味着服务器期望以比客户端能够生成的格式更新的格式使用密码。
$> mysql Client does not support authentication protocol requested by server; consider upgrading MySQL client
请记住,客户端程序使用选项文件或环境变量中指定的连接参数。 如果客户端程序似乎在您未在命令行上指定它们时发送不正确的默认连接参数,请检查任何适用的选项文件和您的环境。 例如,如果您在不使用任何选项运行客户端时收到
Access denied
,请确保您未在任何选项文件中指定旧密码!您可以通过使用
--no-defaults
选项调用客户端程序来抑制客户端程序使用选项文件。 例如$> mysqladmin --no-defaults -u root version
客户端程序使用的选项文件列在 第 6.2.2.2 节,“使用选项文件” 中。 环境变量列在 第 6.9 节,“环境变量” 中。
如果您遇到以下错误,则意味着您使用的
root
密码不正确。$> mysqladmin -u root -pxxxx ver Access denied for user 'root'@'localhost' (using password: YES)
如果即使您未指定密码也出现上述错误,则意味着您在某个选项文件中列出了不正确的密码。 请尝试使用
--no-defaults
选项,如上一项中所述。有关更改密码的信息,请参阅 第 8.2.14 节,“分配帐户密码”。
如果您丢失或忘记了
root
密码,请参阅 第 B.3.3.2 节,“如何重置 root 密码”。localhost
是您本地主机名的同义词,也是客户端在您未明确指定主机的情况下尝试连接的默认主机。您可以使用
--host=127.0.0.1
选项明确命名服务器主机。 这会导致与本地 mysqld 服务器建立 TCP/IP 连接。 您也可以通过指定使用本地主机实际主机名的--host
选项来使用 TCP/IP。 在这种情况下,即使您在与服务器相同的宿主主机上运行客户端程序,也必须在服务器宿主主机上的user
表行中指定主机名。“访问被拒绝”错误消息会告诉您您尝试登录的身份、您尝试连接的客户端主机以及您是否使用了密码。 通常,您应该在
user
表中有一行与错误消息中给出的主机名和用户名完全匹配。 例如,如果您收到包含using password: NO
的错误消息,则意味着您尝试在没有密码的情况下登录。如果您在尝试使用
mysql -u
连接到数据库时收到user_name
Access denied
错误,则您的user
表可能存在问题。 通过执行mysql -u root mysql
并发出以下 SQL 语句来检查这一点。SELECT * FROM user;
结果应包含一个行,其中
Host
和User
列与您的客户端主机名和您的 MySQL 用户名匹配。如果您在尝试从运行 MySQL 服务器的主机以外的主机连接时遇到以下错误,则意味着
user
表中没有Host
值与客户端主机匹配的行。Host ... is not allowed to connect to this MySQL server
您可以通过为尝试连接时使用的客户端主机名和用户名组合设置帐户来解决此问题。
如果您不知道连接机器的 IP 地址或主机名,您应该在
user
表中将'%'
作为Host
列值放入一行。 尝试从客户端机器连接后,使用SELECT USER()
查询查看您实际连接的方式。 然后将user
表行中的'%'
更改为日志中显示的实际主机名。 否则,您的系统将处于不安全状态,因为它允许任何主机对给定用户名进行连接。在 Linux 上,此错误可能发生的另一个原因是您使用的是与您使用的
glibc
库版本不同的版本编译的二进制 MySQL 版本。 在这种情况下,您应该升级操作系统或glibc
,或者下载 MySQL 版本的源代码分发版并自行编译。 源 RPM 通常很容易编译和安装,因此这不是什么大问题。如果您在尝试连接时指定了主机名,但收到一条错误消息,其中未显示主机名或为 IP 地址,则意味着 MySQL 服务器在尝试将客户端主机的 IP 地址解析为名称时遇到错误。
$> mysqladmin -u root -pxxxx -h some_hostname ver Access denied for user 'root'@'' (using password: YES)
如果您尝试以
root
身份连接并收到以下错误,则意味着您在user
表中没有User
列值为'root'
的行,并且 mysqld 无法解析您的客户端主机名。Access denied for user ''@'unknown'
这些错误表明存在 DNS 问题。 要解决此问题,请执行 mysqladmin flush-hosts 以重置内部 DNS 主机缓存。 请参阅 第 7.1.12.3 节,“DNS 查询和主机缓存”。
一些永久解决方案是
确定您的 DNS 服务器存在什么问题并修复它。
在 MySQL 授权表中指定 IP 地址而不是主机名。
在 Unix 上的
/etc/hosts
或 Windows 上的\windows\hosts
中添加客户端机器名的条目。使用启用了
skip_name_resolve
系统变量启动 mysqld。使用
--host-cache-size=0
启动 mysqld。在 Unix 上,如果您在同一台机器上运行服务器和客户端,请连接到
localhost
。 对于到localhost
的连接,MySQL 程序会尝试通过使用 Unix 套接字文件连接到本地服务器,除非有指定连接参数以确保客户端建立 TCP/IP 连接。 有关更多信息,请参阅 第 6.2.4 节,“使用命令选项连接到 MySQL 服务器”。在 Windows 上,如果您在同一台机器上运行服务器和客户端,并且服务器支持命名管道连接,请连接到主机名
.
(句号)。 到.
的连接使用命名管道而不是 TCP/IP。
如果
mysql -u root
正常工作,但mysql -h
导致your_hostname
-u rootAccess denied
(其中your_hostname
是本地主机的实际主机名),则您的user
表中可能没有您的主机的正确名称。 这里的一个常见问题是user
表行中的Host
值指定了一个非限定主机名,但您的系统的名称解析例程返回了一个完全限定的域名(反之亦然)。 例如,如果您在user
表中有一行,其主机为'pluto'
,但您的 DNS 告诉 MySQL 您的主机名为'pluto.example.com'
,则该行不起作用。 尝试在user
表中添加一行,其中包含您的主机的 IP 地址作为Host
列值。(或者,您可以在user
表中添加一行,其Host
值包含通配符(例如,'pluto.%'
)。 但是,使用以%
结尾的Host
值 不安全,并且 不 建议!)如果
mysql -u
正常工作,但user_name
mysql -u
不正常工作,则您没有授予给定用户对名为user_name
some_db
some_db
的数据库的访问权限。如果在服务器宿主主机上执行
mysql -u
正常工作,但在远程客户端宿主主机上执行user_name
mysql -h
不正常工作,则您没有为给定用户名从远程主机启用对服务器的访问权限。host_name
-uuser_name
如果您无法弄清楚为什么出现
Access denied
错误,请从user
表中删除所有包含通配符(包含'%'
或'_'
字符)的Host
值的行。一个非常常见的错误是插入一个新的行,其中Host
='%'
,User
='
,以为这样就能从同一台机器上连接并指定some_user
'localhost
。这种方法之所以不起作用,是因为默认权限包含一行,其中Host
='localhost'
,User
=''
。由于该行具有Host
值'localhost'
,比'%'
更具体,因此在从localhost
连接时,该行优先于新行!正确的操作是插入第二行,其中Host
='localhost'
,User
='
,或删除some_user
'Host
='localhost'
,User
=''
的行。删除该行后,请记住执行FLUSH PRIVILEGES
语句以重新加载授权表。另请参见第 8.2.6 节,“访问控制,阶段 1:连接验证”。如果您能够连接到 MySQL 服务器,但在执行
SELECT ... INTO OUTFILE
或LOAD DATA
语句时始终收到Access denied
消息,则user
表中的您的行没有启用FILE
权限。如果您直接修改授权表(例如,使用
INSERT
、UPDATE
或DELETE
语句),并且您的修改似乎被忽略了,请记住,您必须执行FLUSH PRIVILEGES
语句或mysqladmin flush-privileges命令,以使服务器重新加载权限表。否则,您的更改在服务器下次重启之前将不会生效。请记住,在使用UPDATE
语句修改root
密码后,您无需在刷新权限之前指定新密码,因为服务器直到那时才会知道您已修改了密码。如果您的权限似乎在会话过程中发生了变化,可能是 MySQL 管理员修改了它们。重新加载授权表会影响新的客户端连接,但也会影响现有连接,如第 8.2.13 节,“权限更改生效时间”中所述。
如果您在使用 Perl、PHP、Python 或 ODBC 程序时遇到访问问题,请尝试使用
mysql -u
或user_name
db_name
mysql -u
连接到服务器。如果您能够使用mysql客户端连接,则问题出在您的程序上,而不是访问权限。(user_name
-ppassword
db_name
-p
和密码之间没有空格;您也可以使用--password=
语法指定密码。如果您使用password
-p
或--password
选项且没有密码值,MySQL 会提示您输入密码。)为了进行测试,请使用
--skip-grant-tables
选项启动mysqld服务器。然后,您可以更改 MySQL 授权表,并使用SHOW GRANTS
语句检查您的修改是否产生了预期的效果。当您对更改感到满意时,请执行mysqladmin flush-privileges以告知mysqld服务器重新加载权限。这样一来,您就可以开始使用新的授权表内容,而无需停止和重启服务器。如果其他方法都失败,请使用调试选项(例如,
--debug=d,general,query
)启动mysqld服务器。这将打印有关尝试连接的主机和用户的信息,以及有关执行的每个命令的信息。另请参见第 7.9.4 节,“DBUG 包”。如果您在使用 MySQL 授权表时遇到其他问题,并在MySQL 社区 Slack上寻求帮助,请始终提供 MySQL 授权表的转储。您可以使用mysqldump mysql命令转储这些表。要提交错误报告,请参阅第 1.6 节,“如何报告错误或问题”中的说明。在某些情况下,您可能需要使用
--skip-grant-tables
选项重启mysqld才能运行mysqldump。