mysql 8.0+ 必须先 create user 再 grant,直接 grant 创建用户会报错 error 1410;需分两步显式执行,且注意主机名区分、密码策略、认证插件兼容性、权限粒度及删除前需先 revoke。

MySQL 8.0+ 必须先 CREATE USER 再 GRANT
直接用 GRANT 创建用户会报错 ERROR 1410 (42000): You are not allowed to create a user with GRANT。MySQL 8.0+ 默认禁用该行为,必须显式分两步:先建用户,再赋权。
常见错误是写成:GRANT ALL ON mydb.* TO 'app'@'localhost' IDENTIFIED BY 'pwd123'; —— 这在 8.0+ 里语法不合法,会失败。
- 正确顺序:
CREATE USER 'app'@'localhost' IDENTIFIED BY 'StrongPass!2026';,再GRANT SELECT, INSERT ON mydb.* TO 'app'@'localhost'; - 主机名
'localhost'和'127.0.0.1'在 MySQL 权限系统中视为不同 host,不能混用 - 若需远程访问,用
'app'@'%'或更安全的'app'@'192.168.1.%',但要确认bind-address没锁死为127.0.0.1
密码强度和认证插件不兼容是登录失败主因
新建用户后 mysql -u app -p 连不上?90% 是这两个问题之一:
- 密码不满足策略:执行
SHOW VARIABLES LIKE 'validate_password%';查等级;若为MEDIUM或更高,密码需含大小写字母+数字+特殊字符(如P@ssw0rd2026) - 客户端太老,不支持默认插件
caching_sha2_password:建用户时加IDENTIFIED WITH mysql_native_password BY 'xxx' - 验证用户是否真存在:
SELECT User, Host FROM mysql.user WHERE User = 'app';,注意Host字段必须完全匹配连接时用的地址
GRANT 权限范围写错会导致“有连接无操作”
用户能连上但执行 USE mydb 报 Access denied,或查表失败,往往不是没授权,而是权限粒度或范围不对:
-
GRANT SELECT ON mydb.*允许查所有表,但不等于允许USE mydb—— 实际上USE依赖的是数据库级权限,而SELECT是对象级权限,两者独立 - 想让用户能
CREATE TABLE,必须显式加CREATE权限:GRANT SELECT, INSERT, CREATE ON mydb.* TO 'app'@'localhost'; - 不要用
GRANT ALL PRIVILEGES ON *.*,生产环境应限定到具体库,比如myapp_db.*,避免越权 - 执行完
GRANT后建议仍运行FLUSH PRIVILEGES;,确保立即生效(8.0+ 虽不强制,但可排除缓存干扰)
删用户前必须先 REVOKE,否则权限残留
DROP USER 'app'@'localhost' 只删账号,不自动清理已授出的权限记录——尤其当该用户曾被 GRANT ... WITH GRANT OPTION 授权给别人时,权限链可能还在。
- 安全做法:先回收权限:
REVOKE ALL PRIVILEGES ON mydb.* FROM 'app'@'localhost'; - 再删用户:
DROP USER 'app'@'localhost'; - 检查残留:
SELECT * FROM mysql.tables_priv WHERE User = 'app';(有时列级或过程权限会漏掉)
权限匹配按 User@Host 最精确项优先,比如 'app'@'192.168.1.100' 比 'app'@'%' 优先级高,调试时务必查 mysql.user 表里的实际记录。











