mysql 8.0 必须先 create user 再 grant,否则报 error 1410;因语法强制拆分创建与授权,且默认认证插件为 caching_sha2_password,旧客户端不兼容时需显式指定 mysql_native_password。

MySQL 8.0 必须先 CREATE USER 再 GRANT,否则报 ERROR 1410
直接执行 GRANT ALL ON *.* TO 'admin'@'192.168.10.%' IDENTIFIED BY 'pwd' 在 MySQL 8.0+ 会立刻失败,错误是 ERROR 1410 (42000): You are not allowed to create a user with GRANT。这不是权限不足或密码错,而是语法被移除——8.0 强制拆分创建与授权两步。你必须先用 CREATE USER 显式声明用户和认证方式,再用 GRANT 赋权。
特别注意认证插件:MySQL 8.0 默认用 caching_sha2_password,但很多旧客户端(如某些 PHP 扩展、Navicat 旧版)不兼容。若远程连不上且报 Authentication plugin 'caching_sha2_password' cannot be loaded,建用户时得显式指定 IDENTIFIED WITH mysql_native_password。
CREATE USER 'admin'@'192.168.10.%' IDENTIFIED WITH mysql_native_password BY 'StrongPass!2026';- 不要用
'%'匹配所有主机,除非真需要;优先写具体网段,比如'192.168.10.%'或单 IP'10.0.2.5' - 用户名别用
root,哪怕加了 host 限定,也容易和已有'root'@'localhost'混淆,权限系统里它们是完全独立的账号
只授予远程管理必需的权限,避免 ALL PRIVILEGES
远程管理账号 ≠ 全局超级用户。给 ALL PRIVILEGES ON *.* 等于把删库、改系统表、关服务的权力交出去,一旦泄露或误操作就是灾难。真实运维中,远程管理通常只需以下几类操作:
-
SELECT, INSERT, UPDATE, DELETE:查/改业务数据(按需限制到具体库,如myapp.*) -
SHOW DATABASES, SHOW VIEW, PROCESS:看库列表、查视图定义、看当前连接 -
RELOAD, SHUTDOWN:仅当需要远程重启或刷新配置时才开(生产环境慎开) -
REPLICATION CLIENT:查主从状态,如SHOW SLAVE STATUS - 绝不要给
CREATE USER、GRANT OPTION、FILE、SHUTDOWN(除非你明确要它能停库)
示例(安全保守型):GRANT SELECT, INSERT, UPDATE, DELETE, SHOW DATABASES, SHOW VIEW, PROCESS, REPLICATION CLIENT ON myapp.* TO 'admin'@'192.168.10.%';
bind-address 和防火墙必须同步放开,否则账号再对也连不上
即使 'admin'@'192.168.10.%' 创建成功、权限也给了,如果 MySQL 配置里 bind-address = 127.0.0.1(phpEnv、部分一键包默认值),它根本不会监听外部 TCP 请求——此时从远程 telnet your_ip 3306 一定超时。这不是账号问题,是服务端没“开门”。
- 编辑 MySQL 配置文件(Linux 通常是
/etc/mysql/mysql.conf.d/mysqld.cnf,Windows 是my.ini) - 找到
bind-address行,改为bind-address = 0.0.0.0(监听所有接口)或更安全的bind-address = 192.168.10.100(只绑内网IP) - 重启 MySQL:
sudo systemctl restart mysql(Ubuntu)或net stop mysql && net start mysql(Windows) - 检查是否生效:
sudo ss -tlnp | grep :3306,输出中应含0.0.0.0:3306或对应 IP - 别忘了系统防火墙:Ubuntu 用
sudo ufw allow 3306,CentOS 用sudo firewall-cmd --add-port=3306/tcp --permanent,Windows 防火墙需新增入站规则放行 TCP 3306
权限修改后不用 FLUSH PRIVILEGES,但 host 不匹配会导致静默拒绝
MySQL 8.0+ 的权限变更在 GRANT 执行后立即生效,FLUSH PRIVILEGES 不再必要(除非你手动改了 mysql.user 表)。很多人反复执行它却没解决问题,是因为真正卡点在 host 匹配逻辑上。
'admin'@'192.168.10.%' 和 'admin'@'%' 是两个账号;'admin'@'localhost' 和 'admin'@'127.0.0.1' 也是两个——前者走 Unix socket,后者走 TCP。远程连接时,MySQL 严格按客户端发起连接的源 IP 去匹配 user.host 字段,不模糊、不继承、不 fallback。
- 连不上时,先在服务端执行:
SELECT user, host FROM mysql.user WHERE user = 'admin';,确认返回的host值和你远程连接时用的 IP 完全匹配 - 用
mysql -uadmin -p -h your_server_ip连,服务端看到的 host 就是那个 IP,不是域名也不是localhost - 如果应用服务器在 NAT 后(如 Docker 容器、云函数),实际看到的可能是网关 IP,这时
host得设成网关地址,而不是容器内网段











