如果您尝试连接到 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 密码”。然后,以
root
身份登录,使用--password
(或-p
)选项:$> 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
-
请记住,客户端程序使用在选项文件或环境变量中指定的连接参数。如果客户端程序似乎在未指定命令行选项时发送错误的默认连接参数,请检查适用的选项文件和环境变量!例如,如果您在不带任何选项时运行客户端程序时收到
访问被拒绝
,请确保您没有在任何选项文件中指定旧密码!您可以通过使用
--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 连接。您也可以使用 TCP/IP 通过指定--host
选项,该选项使用本地主机的实际主机名。在这种情况下,主机名必须在服务器主机上的user
表行中指定,即使您是在同一主机上运行客户端程序。 -
错误消息
Access denied
告诉您尝试登录的用户名、客户端主机名和是否使用密码。通常,您应该在user
表中拥有一个与错误消息中给出的主机名和用户名完全匹配的行。例如,如果您收到包含using password: NO
的错误消息,这意味着您尝试登录时没有密码。 -
如果您在尝试连接数据库时收到
Access denied
错误,例如使用mysql -u
,您可能有一个user_name
user
表问题。请通过执行mysql -u root mysql
并发出以下 SQL 语句来检查:SELECT * FROM user;
结果应该包括一个与客户端主机名和 MySQL 用户名匹配的
Host
和User
列。 -
如果您在尝试从其他主机连接时收到以下错误,这意味着没有一个
user
表行的Host
值与客户端主机名匹配:Host ... is not allowed to connect to this MySQL server
您可以通过设置客户端主机名和用户名的组合账户来修复此问题。
如果您不知道连接的机器的IP地址或主机名,您应该在
user
表中添加一行,Host
列值为'%'
。然后,在客户机上尝试连接,使用SELECT USER()
查询来查看实际连接的方式。然后,将user
表中的'%'
更改为实际显示在日志中的主机名。否则,您的系统将变得不安全,因为它允许来自任何主机的连接。在Linux上,另一个可能导致该错误的原因是您使用的MySQL二进制版本与您使用的
glibc
库版本不同。在这种情况下,您可以升级操作系统或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。 -
在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
表中添加一行,其中Host
列值为您的主机IP地址。(或者,您可以在user
表中添加一行,其中Host
值以%
结尾,例如'pluto.%'
。然而,使用以%
结尾的Host
值是不安全的并且不推荐!) -
如果
mysql -u
工作正常,但用户名
mysql -u
不工作,则您没有授予给定用户对名为用户名
某数据库
某数据库
的数据库的访问权限。 -
如果
mysql -u
在服务器主机上工作正常,但用户名
mysql -h
在远程客户端主机上不工作,则您没有启用对服务器的访问权限 для给定的用户名从远程主机。主机名
-u用户名
-
如果您无法弄清楚为什么您收到
访问被拒绝
,请从user
表中删除所有包含通配符(包含'%'
或'_'
字符)的行。一个非常常见的错误是插入一个新的行,Host
='%'
和User
='
,认为这将启用您从同一台机器连接的 localhost。这种方法不起作用的原因是默认权限包括一行某用户
'Host
='localhost'
和User
=''
。因为该行的Host
值'localhost'
比'%'
更具体,所以它优先于新行连接到localhost
!正确的过程是插入第二行,Host
='localhost'
和User
='
,或删除行某用户
'Host
='localhost'
和User
=''
。删除行后,记住发出FLUSH PRIVILEGES
语句以重新加载权限表。另请参阅 第 8.2.6 节,“访问控制,阶段 1:连接验证”。 -
如果您能够连接到 MySQL 服务器,但在发出
SELECT ... INTO OUTFILE
或LOAD DATA
语句时总是收到访问被拒绝
消息,则您的user
表行没有启用FILE
权限。 -
如果您直接更改权限表(例如,使用
INSERT
、UPDATE
或DELETE
语句),并且您的更改似乎被忽略,请记住您必须执行FLUSH PRIVILEGES
语句或 mysqladmin flush-privileges 命令,以便服务器重新加载权限表。否则,您的更改将不生效,直到下一次服务器重新启动。请记住,在更改root
密码后,您不需要指定新密码,直到您刷新权限后,因为服务器不知道您已经更改了密码。 -
如果您的权限似乎在会话中间更改了,可能是 MySQL 管理员已经更改了它们。重新加载权限表会影响新的客户端连接,也会影响现有的连接,如 第 8.2.13 节,“权限更改何时生效” 中所示。
-
如果您在使用 Perl、PHP、Python 或 ODBC 程序时遇到访问问题,请尝试使用
mysql -u
或用户名
数据库名
mysql -u
连接到服务器。如果您可以使用 mysql 客户端连接,则问题在于您的程序,而不是访问权限。(在用户名
-p密码
数据库名
-p
和密码之间没有空格;您也可以使用--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.5 节,“如何报告错误或问题”。在某些情况下,您可能需要使用
--skip-grant-tables
选项重新启动 mysqld,以便运行 mysqldump。