mysql 8.0远程连接失败主因是caching_sha2_password认证插件不兼容、bind-address=127.0.0.1未监听外部ip、防火墙或云安全组未放行3306端口,以及root@localhost权限无法匹配远程地址,四者缺一不可。

直接改 root 的 host 为 % 并开放 3306 端口,不是“能连上”就完事了——MySQL 8.0 的远程访问失败,90% 是卡在认证插件、bind-address 或防火墙三者之一,剩下 10% 是权限没刷或云平台安全组没配。
为什么 root@localhost 无法远程连接?
MySQL 8.0 默认用 caching_sha2_password 插件认证,而很多客户端(如旧版 Navicat、某些 JDBC 驱动)只认 mysql_native_password。同时,user 表里 root 的 host 字段是 localhost,它和 127.0.0.1、% 是三个完全不同的账户,不能混用。
- 执行
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';查看当前生效的 root 账户行 - 如果只有
root@localhost,那远程连接根本不会命中这一行,直接报Access denied for user 'root'@'xxx' - 不要试图用
UPDATE user SET host = '%' WHERE user = 'root';强改已有行——这会破坏localhost本地登录,且不解决认证插件问题
创建专用远程用户比改 root 更安全也更可靠
生产环境禁止直接暴露 root 远程访问。应该新建一个带明确 IP 限制、最小权限、固定认证方式的用户:
- 先确认 MySQL 监听地址:检查
/etc/mysql/mysql.conf.d/mysqld.cnf(Ubuntu)或C:\ProgramData\MySQL\MySQL Server 8.0\my.ini(Windows)中的bind-address,必须是0.0.0.0或服务器实际 IP,不能是127.0.0.1 - 用以下语句创建用户(示例中限定仅允许来自
192.168.1.100的连接):CREATE USER 'app_dbuser'@'192.168.1.100' IDENTIFIED WITH mysql_native_password BY 'StrongPass!2026';
- 授予权限时避免
GRANT ALL ON *.*,例如只给某个库:GRANT SELECT, INSERT, UPDATE ON myapp_db.* TO 'app_dbuser'@'192.168.1.100';
- 最后必须执行
FLUSH PRIVILEGES;,否则权限不生效
防火墙和云平台安全组常被忽略
MySQL 配置全对,但连不上?大概率是网络层拦截。注意三层过滤:
- 系统防火墙:Ubuntu 用
sudo ufw allow 3306;CentOS 用sudo firewall-cmd --permanent --add-port=3306/tcp && sudo firewall-cmd --reload - 云服务器安全组(如阿里云、腾讯云):必须手动添加入方向规则,协议 TCP,端口 3306,源 IP 建议填具体客户端 IP 或网段,别直接填
0.0.0.0/0 - SELinux(仅 CentOS/RHEL):若启用,需运行
sudo setsebool -P mysqld_connect_any on,否则即使端口通也会被静默拒绝
测试连接前务必验证监听状态
别急着开 Navicat,先用最简方式确认服务是否真正对外可访问:
- 在数据库服务器本机执行:
ss -tlnp | grep :3306,输出中应含0.0.0.0:3306或具体 IP,而非127.0.0.1:3306 - 从客户端机器执行:
telnet your_mysql_ip 3306或nc -zv your_mysql_ip 3306,通了才说明网络和防火墙没问题 - 再用 MySQL 客户端命令测试认证:
mysql -h your_mysql_ip -u app_dbuser -p,输入密码后能进就说明权限和插件都 OK
最容易被跳过的点是:改了配置文件却没重启 MySQL 服务,或者改了 user 表但忘了 FLUSH PRIVILEGES;还有就是云平台安全组规则没生效(有时要等 30 秒)。这些地方一漏,前面所有操作都白做。











