• 发生时间:2022-11-10

  • 问题描述:

    • 在服务器的终端连接 mysql,返回错误,如下所示:
    -> % mysql -u username -p
    Enter password:
    ERROR 1045 (28000): Access denied for user 'username'@'localhost' (using password: YES)
    
  • 问题类别:软件维护

  • 原因分析:

    • 首先确认账号和密码是否输入错误:多次检查代码和配置文件,并重复输入账号和密码,依然失败。排除这一可能性。
    • 然后确认 mysqld 是否正常启动:
    -> % netstat -lnpt | grep 330
    (Not all processes could be identified, non-owned process info
     will not be shown, you would have to be root to see it all.)
    tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      -
    tcp        0      0 127.0.0.1:3307          0.0.0.0:*               LISTEN      -
    
    • netstat 的输出结果发现服务器同时监听了 3306 和 3307 两个端口,3306 是 mysqld 默认端口,3307 看上去也像 mysqld 监听的端口, 但 mysqld 只能监听一个端口,这是什么回事?
    • 于是咨询服务器的维护人员,得知:3306 是本服务器的 mysqld 监听的端口,3307 则是通过端口映射连接到测试服务器的 mysqld 监听的端口。
    • 我现在要连接的是测试环境的数据库,因此需要指定端口号为 3307. 因此,我加上端口号后再尝试连接,发现仍然失败。
    -> % mysql -P 3307 -u username -p
    Enter password:
    ERROR 1045 (28000): Access denied for user 'username'@'localhost' (using password: YES)
    
    • 后来,我想起 netstat 的输出结果中 mysqld 监听的 ip 是 127.0.0.1,猜测可能要指定 host,测试发现果然可以成功连接了。
    -> % mysql -h 127.0.0.1 -P 3307 -u username -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    # 省略后面的打印信息
    
    • 另外,我试了将 127.0.0.1 改为 localhost,发现也会无法连接。看来 -h 的参数还必须跟 mysqld 监听的 ip 地址保持一致。
  • 解决方案:使用 mysql -h 127.0.0.1 -P 3307 -u username -p 来连接 mysqld。

  • 实施结果:可以成功连接 mysqld。

  • 经验总结:

    • 当 mysqld 没监听在默认端口时,连接 mysqld 需要同时指定 host 和 port,并且 host 的取值必须跟 mysqld 监听的 ip 地址保持一致。 (比如 mysqld 监听在 127.0.0.1,那么 host 也必须填写这个值,不能填 localhost。)