Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Troubleshooting Problems Connecting to 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 套接字文件,而不是服务器监听的端口。要解决这个问题,在调用客户端程序时,使用 --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 节,“Postinstallation Setup and Testing”

    要确定是否需要初始化授权表,检查 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:

    然而,服务器将允许您连接为root而不使用密码,如果您使用mysqld --initialize-insecure初始化MySQL(详见第2.9.1节,“初始化数据目录”)。这是一种安全风险,因此您应该为root账户设置密码;详见第2.9.4节,“初始MySQL账户的安全性”

  • 如果您已经更新了现有MySQL安装到最新版本,是否执行了MySQL升级过程?如果没有,请执行。 grant表的结构偶尔会因为添加新功能而改变,因此在升级后总是确保您的表具有当前结构。详见第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节,“Assigning Account Passwords”

    如果你已经忘记了root密码,请见第B.3.3.2节,“How to Reset the Root Password”

  • localhost是本地主机的同义词,也是客户端连接到服务器时的默认主机,如果你没有指定主机。

    你可以使用--host=127.0.0.1选项来指定服务器主机。这将导致对本地mysqld服务器的TCP/IP连接。你也可以使用TCP/IP来指定实际的主机名。这种情况下,主机名必须在服务器主机上的user表行中指定,即使你在同一主机上运行客户端程序。

  • Access denied错误消息将告诉你你试图以什么身份登录,来自哪个客户端主机,你是否使用了密码。通常,你应该在user表中有一行精确匹配错误消息中的主机名和用户名。例如,如果你收到包含using password: NO的错误消息,那么意味着你试图以无密码方式登录。

  • 如果你在尝试连接到数据库时收到Access denied错误,使用mysql -u user_name,可能是user表的问题。检查这个问题,可以执行mysql -u root mysql,然后执行以下SQL语句:

    SELECT * FROM user;

    结果应该包括一个行,其中HostUser列匹配你的客户端主机名和你的MySQL用户名。

  • 如果出现的错误在你从非服务器主机连接时出现,那么意味着user表中没有一个Host值匹配客户端主机:

    Host ... is not allowed to connect to this MySQL server

    你可以通过为客户端主机名和用户名设置账户来解决这个问题。

    如果您不知道连接的机器的IP地址或主机名,您应该在user表中添加一行,Host列值为'%'。然后,在客户端机器上使用SELECT USER()查询来查看实际连接的主机名。然后,在user表中将'%'更改为实际主机名,以免系统留下不安全的连接。

    在Linux上,可能的原因是您使用的MySQL版本与glibc库版本不同。在这种情况下,您可以升级操作系统或glibc,或者下载MySQL源代码并自己编译。

  • 如果您指定主机名连接,但收到错误信息,其中主机名不显示或是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文件中。

    • 启动mysqld并启用skip_name_resolve系统变量。

    • 启动mysqld并使用--host-cache-size=0

    • 在Unix上,如果您在同一台机器上运行服务器和客户端,连接到localhost。MySQL程序将尝试连接到本地服务器使用Unix socket文件,除非指定连接参数以确保客户端使用TCP/IP连接。更多信息,请参阅第6.2.4节,“使用命令选项连接到MySQL服务器”

    • 在 Windows 平台上,如果您在同一台机器上运行服务器和客户端,并且服务器支持命名管道连接,可以连接到主机名 . (点号)。对 . 的连接使用命名管道,而不是 TCP/IP。

  • 如果 mysql -u root 可以工作,但是 mysql -h your_hostname -u root 结果为 Access denied(其中 your_hostname 是实际的主机名),您可能没有正确的主机名在 user 表中。常见的问题是,Host 值在 user 表行中指定了未qualified 主机名,但您的系统名称解析程序返回完全合格域名(或 vice versa)。例如,如果您在 user 表中有一个行,其中主机名为 'pluto',但您的 DNS 告诉 MySQL 您的主机名为 'pluto.example.com',该行将无法工作。尝试将包含您主机的 IP 地址的行添加到 user 表的 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',认为这可以使您从同一台机器连接。然而,这不起作用是因为默认权限包括一个行,Host='localhost'User=''。因为该行的Host'localhost''%'更具体,因此在连接到localhost时将使用该行,而不是新行!正确的步骤是插入一个新的行,Host='localhost'User='some_user',或者删除Host='localhost'User=''的行。删除行后,记住执行一个FLUSH PRIVILEGES语句以重新加载授权表。见第8.2.6节,“Access Control, Stage 1: Connection Verification”

  • 如果您能够连接到MySQL服务器,但每次执行SELECT ... INTO OUTFILELOAD DATA语句时都出现Access denied消息,您的行在user表中没有启用FILE权限。

  • 如果您直接更改授权表(例如,使用INSERTUPDATEDELETE语句),并且您的更改似乎被忽略,记住您必须执行一个FLUSH PRIVILEGES语句或一个mysqladmin flush-privileges命令,以便服务器重新加载授权表。否则,您的更改将无效,直到服务器重新启动。记住,在更改root密码后,您不需要直到flush权限时指定新密码,因为服务器不知道您已经更改了密码。

  • 如果您的权限似乎在会话中发生了变化,可能是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将提示您输入密码。)

  • 为了测试目的,使用mysqld服务器的--skip-grant-tables选项。然后,您可以更改MySQL授权表,并使用SHOW GRANTS语句检查您的修改是否生效。当您满意您的更改后,执行mysqladmin flush-privileges以通知mysqld服务器重新加载权限。这使您可以开始使用新的授权表内容,而无需停止和重新启动服务器。

  • 如果一切都失败,使用mysqld服务器的调试选项(例如--debug=d,general,query)。这将打印主机和用户信息关于尝试的连接,以及每个命令的信息。见第7.9.4节,“DBUG包”

  • 如果您遇到与 MySQL 授權表相关的问题,可以在 MySQL 社区 Slack 上询问,总是提供 MySQL 授權表的备份。您可以使用 mysqldump mysql 命令来备份表。要提交错误报告,请查看 第1.6节,“如何报告错误或问题”。在某些情况下,您可能需要使用 mysqld 命令,带有 --skip-grant-tables 选项,以便运行 mysqldump