MySQL 8.0+必须先CREATE USER再GRANT,因IDENTIFIED BY语法已被移除,直接GRANT不存在用户会报ERROR 1410;需确保user@host完全匹配、认证插件兼容(如mysql_native_password),并正确配置bind-address与防火墙。

MySQL 8.0 必须先 CREATE USER 再 GRANT
直接 GRANT 一个不存在的用户会报错:ERROR 1410 (42000): You are not allowed to create a user with GRANT。这是 MySQL 8.0+ 的默认行为,不是 phpEnv 或配置问题,而是服务端策略变更。
正确流程只有两步,缺一不可:
- 先建用户:
CREATE USER 'app'@'127.0.0.1' IDENTIFIED BY 'MyPass!2026'; - 再赋权:
GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'app'@'127.0.0.1';
注意:主机名别盲目写 '%'——phpEnv 默认 bind-address = 127.0.0.1,'app'@'localhost' 和 'app'@'127.0.0.1' 在权限系统里是两个独立账号(前者走 socket,后者走 TCP),连不上大概率是用了错的 host。
远程访问要改 bind-address,不是只改 host
即使你创建了 'app'@'%' 并 GRANT 了权限,如果 MySQL 配置里 bind-address = 127.0.0.1(phpEnv 默认如此),那它根本不会监听外部请求,telnet your_ip 3306 一定超时。
操作路径:phpEnv\MySQL\conf\my.ini,找到并修改这一行:
bind-address = 0.0.0.0
改完必须重启 MySQL 服务,否则不生效。顺带检查 Windows 防火墙是否放行了 3306 端口——没开防火墙,远程连接永远卡在 “Connection timed out”。
caching_sha2_password 认证失败?显式指定 mysql_native_password
PHP 7.x、旧版 Navicat、某些 Python pymysql(尤其 0.x 版本)不支持 MySQL 8.0 默认的 caching_sha2_password 插件,会报类似 Authentication plugin 'caching_sha2_password' cannot be loaded 或直接拒绝连接。
解决方法是在建用户时强制指定认证方式:
CREATE USER 'app'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'MyPass!2026';
或者对已有用户更新:
ALTER USER 'app'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'MyPass!2026';
执行后务必跟一句 FLUSH PRIVILEGES;,phpEnv 下偶有权限缓存未自动刷新,导致“明明改了却还是连不上”。
权限范围写错会导致 Access denied 但不提示具体原因
常见误操作:GRANT SELECT ON mydb.* TO 'app'@'127.0.0.1'; 看似给了读权限,但应用实际执行了 CREATE TABLE 或 DROP TABLE ——这些命令需要数据库级或全局权限,mydb.* 范围下不包含。
判断依据看错误信息关键词:
-
CREATE command denied→ 缺CREATE权限,得加GRANT CREATE ON mydb.*或GRANT CREATE ON *.*(后者慎用) -
Access denied for user 'app'@'127.0.0.1'→ 先确认 host 是否匹配、密码是否用对插件、FLUSH PRIVILEGES是否执行 -
Table 'mysql.user' doesn't exist→ 连错了库,不是权限问题,是 SQL 执行环境错误
最小权限原则在这里特别重要:Laravel 迁移要 CREATE、DROP、INDEX;ThinkPHP 可能还要 EXECUTE(调存储过程)。别图省事给 ALL PRIVILEGES ON *.*,尤其是生产环境。


















