文档主页
MySQL 8.4 参考手册
相关文档 下载此手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  连接到 MySQL 时出现的问题排查

8.2.22 连接到 MySQL 时出现的问题排查

如果您在尝试连接到 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 套接字文件不同的端口、命名管道或 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 的目录。(数据目录通常名为 datavar,并且位于您的 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 表行中指定主机名。

  • “Access denied” 错误消息会告诉您要尝试以什么身份登录,尝试连接的客户端主机以及是否使用密码。通常,user 表中应该有一行与错误消息中给出的主机名和用户名完全匹配。例如,如果收到包含 using password: NO 的错误消息,则表示您尝试在没有密码的情况下登录。

  • 如果您在尝试使用 mysql -u user_name 连接到数据库时收到 Access denied 错误,则 user 表可能存在问题。可以通过执行 mysql -u root mysql 并发出以下 SQL 语句来检查这一点。

    SELECT * FROM user;

    结果应该包含一行,其中 HostUser 列与客户端的主机名和 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 root 导致出现 Access 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 -u user_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 OUTFILELOAD DATA 语句时始终收到 Access denied 错误,则 user 表中的您的行没有启用 FILE 权限。

  • 如果您直接修改授权表(例如,使用 INSERTUPDATEDELETE 语句),并且修改似乎被忽略,请记住您必须执行 FLUSH PRIVILEGES 语句或 mysqladmin flush-privileges 命令,以使服务器重新加载权限表。否则,您的修改在下次服务器重新启动之前不会生效。请记住,使用 UPDATE 语句修改 root 密码后,在刷新权限之前,您不需要指定新密码,因为服务器在此之前不知道您已经修改了密码。

  • 如果您的权限似乎在会话中途发生了改变,可能是因为 MySQL 管理员修改了权限。重新加载授权表会影响新的客户端连接,还会影响现有连接,如 第 8.2.13 节,“权限更改何时生效” 中所述。

  • 如果使用 Perl、PHP、Python 或 ODBC 程序遇到访问问题,请尝试使用 mysql -u user_name db_namemysql -u user_name -ppassword db_name 连接到服务器。如果您能够使用 mysql 客户端连接,则问题出在您的程序上,而不是访问权限。(-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 Community Slack 上寻求帮助,请始终提供 MySQL 授权表的转储。您可以使用 mysqldump mysql 命令转储表。要提交错误报告,请参阅 第 1.6 节,“如何报告错误或问题” 中的说明。在某些情况下,您可能需要使用 --skip-grant-tables 选项重新启动 mysqld,才能运行 mysqldump