You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从VPS无法连接远程MySQL服务器,本地桌面可正常连接求助

解决MySQL 1045 Access Denied错误的排查步骤

看起来你遇到的问题核心是MySQL用户的主机匹配规则没搞对——毕竟MySQL的用户是「用户名@主机」的组合,只有当连接请求的来源主机和用户配置的host完全匹配时,才能通过认证。结合你的两种操作场景,我整理了具体的排查和解决方法:

一、先搞清楚错误提示里的@localhost是什么意思

你提到操作a(从另一VPS连接)时,错误提示是'username'@'localhost',这有点反常——正常来说从远程IP连接的话,错误里应该显示@'你的VPS_IP'。这大概率是因为:

  • 你创建的新用户的host设成了localhost,但实际连接来源是远程VPS的IP,MySQL找不到匹配的用户,就 fallback 到了本地的用户规则;
  • 或者你的Python连接代码里,不小心把host写成了localhost而不是远程MySQL服务器的公网IP。

对于操作b(本地VPS连接本地MySQL),如果错误提示@localhost,可能是你创建的用户host和实际连接方式不匹配:MySQL里localhost是通过Unix socket连接,而127.0.0.1是通过TCP/IP连接,这俩是不同的主机身份。

二、具体排查和解决步骤

1. 检查现有用户的主机配置

先登录到你的MySQL服务器,执行以下命令查看所有用户的host属性:

SELECT user, host FROM mysql.user;
  • 对于操作a的远程用户:你需要确保存在'你的用户名'@'另一VPS的IP'或者'你的用户名'@'%'(允许所有IP连接)的用户;
  • 对于操作b的本地用户:如果你的Python代码用host='127.0.0.1'连接,需要存在'你的用户名'@'127.0.0.1'的用户;如果用host='localhost',则需要'你的用户名'@'localhost'的用户。

2. 正确创建用户并授权

根据你的场景重新创建用户(替换掉括号里的内容):

场景a:从指定VPS IP连接

-- 创建允许指定IP连接的用户
CREATE USER 'your_username'@'x.x.x.x' IDENTIFIED BY 'your_password';
-- 授权访问指定数据库(*.*表示所有数据库,按需修改)
GRANT ALL PRIVILEGES ON your_database.* TO 'your_username'@'x.x.x.x';
-- 刷新权限使其生效
FLUSH PRIVILEGES;

如果要允许所有IP连接,把x.x.x.x换成%即可,但注意生产环境不要随便用%,尽量限制IP范围。

场景b:本地VPS连接本地MySQL

如果用TCP/IP连接(Python代码里host='127.0.0.1'):

CREATE USER 'local_user'@'127.0.0.1' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON your_database.* TO 'local_user'@'127.0.0.1';
FLUSH PRIVILEGES;

如果用Unix socket连接(Python代码里host='localhost'或者不指定host):

CREATE USER 'local_user'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON your_database.* TO 'local_user'@'localhost';
FLUSH PRIVILEGES;

3. 检查Python连接代码的参数

确保代码里的host参数和用户的host配置对应:

场景a的连接代码示例:

import mysql.connector

try:
    cnx = mysql.connector.connect(
        host='mysql_server_public_ip',  # 必须是远程MySQL的公网IP,不能是localhost
        user='your_username',
        password='your_password',
        database='your_database'
    )
    print("连接成功!")
    cnx.close()
except mysql.connector.Error as err:
    print(f"错误: {err}")

场景b的连接代码示例:

import mysql.connector

try:
    cnx = mysql.connector.connect(
        host='127.0.0.1',  # 对应user@127.0.0.1
        # 或者 host='localhost' 对应user@localhost
        user='local_user',
        password='your_password',
        database='your_database'
    )
    print("连接成功!")
    cnx.close()
except mysql.connector.Error as err:
    print(f"错误: {err}")

4. 排查匿名用户干扰

如果MySQL里存在匿名用户(user为空的用户),可能会优先匹配导致认证失败。执行以下命令删除匿名用户:

DROP USER ''@'localhost';
DROP USER ''@'127.0.0.1';
FLUSH PRIVILEGES;

5. 确认MySQL确实监听0.0.0.0

虽然你说bind-address设成了0.0.0.0,但还是要验证一下:
在MySQL服务器上执行:

netstat -tulpn | grep 3306

如果输出里有0.0.0.0:3306或者:::3306,说明监听正常;如果只有127.0.0.1:3306,说明配置没生效,需要:

  • 找到MySQL的配置文件(通常是/etc/mysql/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf);
  • 确保bind-address = 0.0.0.0,并且没有被注释;
  • 重启MySQL服务:sudo systemctl restart mysql(Ubuntu/Debian)或sudo service mysqld restart(CentOS/RHEL)。

三、总结

绝大多数1045错误都是「用户-主机」组合不匹配导致的,只要确保你创建的用户host和实际连接的来源(远程IP/本地socket/TCP)完全对应,再配合正确的授权和权限刷新,问题就能解决。

内容的提问来源于stack exchange,提问作者Quantitative

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 13:37:51