mysql根本不监听外部请求,因bind-address=127.0.0.1仅响应本地连接;须改为0.0.0.0并重启服务,再配合用户host权限、防火墙及云安全组开放3306端口。

bind-address 仍为 127.0.0.1,MySQL 根本不监听外部请求
即使 user 表里 host 字段已设为 %,如果 MySQL 服务本身只绑定了 127.0.0.1,那它压根不会接收任何来自网卡的连接请求——远程客户端连 SYN 都发不过去。
验证方法:sudo ss -tlnp | grep :3306 或 sudo netstat -tulnp | grep :3306。若输出中显示的是 127.0.0.1:3306 而非 *:3306 或 0.0.0.0:3306,就说明配置没生效。
- 配置文件路径通常为
/etc/mysql/mysql.conf.d/mysqld.cnf(Debian/Ubuntu)或/etc/my.cnf(CentOS/RHEL),在[mysqld]段下找bind-address - 必须显式设为
bind-address = 0.0.0.0;注释掉该行不一定生效,某些版本默认仍读取内置值 - 改完务必重启服务:
sudo systemctl restart mysql(不是reload) - MySQL 8.0+ 某些 Docker 镜像或云数据库托管实例会禁用该配置项,需查文档确认是否支持自定义绑定地址
GRANT 语法在 MySQL 8.0+ 失效,CREATE USER 和 GRANT 必须分两步
直接执行 GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY 'pwd' 在 MySQL 8.0+ 会报错 ERROR 1410 (42000): You are not allowed to create a user with GRANT——因为 8.0 拆分了用户创建和权限授予逻辑,旧语法被废弃。
正确做法是先确保用户存在,再授权:
- 若用户不存在:先运行
CREATE USER 'root'@'%' IDENTIFIED BY 'your_password'; - 再运行
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; - 最后必须执行
FLUSH PRIVILEGES;,否则内存权限缓存不更新 - 注意:MySQL 8.0 默认认证插件是
caching_sha2_password,部分旧客户端不兼容,可加ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';降级兼容
防火墙或云平台安全组未放行 3306 端口,连接在传输层就被拦截
本地能连、远程 telnet xxx.xxx.xxx.xxx 3306 超时,大概率是流量没到 MySQL 进程——系统防火墙或云服务商的安全组规则拦住了。
- Linux 主机上检查:
sudo ufw status(Ubuntu)或sudo firewall-cmd --list-ports(CentOS) - 必须显式开放 TCP 3306:
sudo ufw allow 3306/tcp或sudo firewall-cmd --permanent --add-port=3306/tcp - 云服务器(阿里云/腾讯云/华为云)必须额外登录控制台,在「安全组」里添加入方向规则:协议类型 TCP,端口范围 3306,源 IP 可填
0.0.0.0/0(测试用)或限定具体 IP 段 - 有些 VPS 提供商(如 DigitalOcean)还有一层「网络防火墙」,需单独配置,不在系统内
用户 host 匹配失败:localhost 和 % 不是同一账户,且优先级有隐含规则
MySQL 认证时,会按 user@host 组合精确匹配,并遵循“最长前缀匹配”原则。比如你有 'root'@'localhost' 和 'root'@'%' 两条记录,从本地连会命中前者;但从远程连,若 DNS 反查把客户端 IP 解析成某个域名(如 web-server.internal),而你又没建 'root'@'web-server.internal',就会匹配失败。
- 执行
SELECT host, user FROM mysql.user;查看所有账户,确认目标 host 是否真实存在且拼写一致(注意空格、大小写) -
%不匹配localhost,这是 MySQL 的硬性设计;若需本地+远程都可用,得保留'root'@'localhost'并另建'root'@'%' - 避免使用
UPDATE mysql.user SET host = '%'直接改表——可能破坏密码哈希字段(尤其 8.0+ 使用caching_sha2_password插件时),应始终用CREATE USER+GRANT - 连接时明确指定 host:
mysql -h your_server_ip -u root -p,避免客户端自动 fallback 到 socket 连接
实际排查时最容易被跳过的是 bind-address 和云安全组——两者一漏,前面所有 SQL 授权操作都白做。别急着改权限表,先用 ss -tlnp 和 telnet ip 3306 确认服务端口是否真正对外暴露。











