mysql 5.7+ root用户默认host为localhost,仅允许本地连接;需用alter user和create user配合grant添加'root'@'%'并指定兼容认证插件,同时修改bind-address、开放防火墙及云安全组。

mysql 5.7+ root 用户 host 为 localhost 时无法远程连接
MySQL 默认安装后,root 用户的 host 字段是 'localhost',这意味着它只接受来自本机 Unix socket 或 127.0.0.1 的连接,哪怕你用 -h 127.0.0.1 也走不了 TCP(取决于配置),更别说外网 IP。这不是密码错,也不是防火墙没开,而是权限记录本身拒绝了远程来源。
- 先确认当前 root 的 host 值:
SELECT User, Host FROM mysql.user WHERE User = 'root';
- 如果结果里只有
'root'@'localhost',那远程连不上就是这个原因 - 不要直接 UPDATE
mysql.user表 —— MySQL 5.7+ 要求用ALTER USER或CREATE USER配合GRANT,否则可能触发认证插件不兼容(比如caching_sha2_password)
正确做法:用 ALTER USER 修改 root 的 host 并指定认证插件
直接改 Host 字段不仅危险,还常因认证插件不匹配导致登录失败。MySQL 8.0 默认用 caching_sha2_password,而老客户端(如某些 Python MySQLdb、旧版 Navicat)只支持 mysql_native_password。
- 登录本地 MySQL:
mysql -u root -p
- 执行(以允许所有 IP 为例,生产环境请换具体 IP):
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
- 再创建通配 host 的 root(或直接重命名原用户):
CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
- 赋权:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
- 刷新:
FLUSH PRIVILEGES;
mysqld 配置必须监听非 127.0.0.1 地址
即使权限开了,mysqld 默认可能只绑定了 127.0.0.1,远程请求根本进不来。
- 检查当前绑定:
netstat -tlnp | grep :3306
,如果只看到127.0.0.1:3306,说明没对外暴露 - 编辑配置文件(常见路径:
/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf) - 找到
bind-address行,改为:bind-address = 0.0.0.0
(或具体内网 IP,不建议直接 0.0.0.0 暴露到公网) - 重启服务:
sudo systemctl restart mysql
(Ubuntu/Debian)或sudo systemctl restart mysqld
(CentOS/RHEL)
防火墙和云服务器安全组经常被忽略
MySQL 端口(默认 3306)在系统防火墙和云平台安全组里都得放行,缺一不可。很多人改完权限、配好 bind-address,却卡在这两层。
- Linux 防火墙(ufw):
sudo ufw allow 3306
- iptables(若启用):
sudo iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
- 阿里云 / 腾讯云控制台:进「安全组」规则页,添加入方向 TCP:3306,源 IP 设为
0.0.0.0/0(测试用)或具体客户端 IP(生产推荐) - 验证是否可达:
telnet your-server-ip 3306
,能连上才说明网络层通了
实际连的时候,如果报 Access denied for user 'root'@'x.x.x.x',八成是 mysql.user 里没有对应 'root'@'x.x.x.x' 或 'root'@'%' 的记录,或者认证插件不匹配 —— 别急着搜“忘记密码”,先查 SELECT User, Host, plugin FROM mysql.user;。











