mysql 8.0+ 要求创建用户与授权分离,grant 不再支持 identified by;flush privileges 多数情况可省略;root@localhost 与 root@% 是独立账号;alter user 仅管理账户属性,grant/revoke 才管理权限。

MySQL 5.7 和 8.0+ 的 GRANT 语法不兼容
直接复用老版本语句在 8.0+ 上会报 ERROR 1064 (42000),核心区别是:8.0+ 拆分了「创建用户」和「赋予权限」两个动作,IDENTIFIED BY 不再允许出现在 GRANT 语句里。
常见错误写法(5.7 可用,8.0+ 报错):GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
正确写法(8.0+ 必须分两步):
- 先创建用户:
CREATE USER 'root'@'%' IDENTIFIED BY '123456'; - 再授权:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
5.7 可以一步完成,但 8.0+ 执行会直接失败——不是警告,是硬性语法拒绝。
FLUSH PRIVILEGES 在 8.0+ 中多数情况可省略
FLUSH PRIVILEGES 在 5.7 及更早版本中常被当作“生效必需步骤”,但在 8.0+ 中,只要用 GRANT 或 REVOKE 修改权限,变更立即持久化并自动生效到新连接;FLUSH PRIVILEGES 只在极少数场景有用(比如你手动改了系统表又没走 SQL 授权路径)。
容易踩的坑:
- 执行完
GRANT还习惯性敲FLUSH PRIVILEGES—— 没错,但没必要,且可能掩盖权限未生效的真实原因(比如 host 匹配失败) - 误以为不刷就“没生效”,其实只是当前连接缓存旧权限,新开一个 mysql 连接就能看到新权限
- 在 8.0+ 中对
mysql.user表做UPDATE后再FLUSH,大概率无效,甚至触发权限校验异常
root@localhost 和 root@% 是两个独立账号
MySQL 不会自动同步不同 host 的权限。执行 SHOW GRANTS FOR 'root'@'localhost' 和 SHOW GRANTS FOR 'root'@'%' 结果往往不同——这很常见,也容易被当成 bug。
同步权限不能靠复制粘贴字段,必须显式重授:
- 查出
'root'@'localhost'的所有GRANT语句(用SHOW GRANTS) - 把每条里的
'root'@'localhost'替换成'root'@'%' - 逐条执行替换后的语句(注意:不要用
UPDATE mysql.user,8.0+ 已禁用该方式)
漏掉某一条(比如 RELOAD 或 SHUTDOWN),远程连接时就可能遇到“权限不足”却查不到原因。
ALTER USER 和 GRANT 的分工必须分清
8.0+ 强制区分账户属性和对象权限:ALTER USER 只管密码、锁定状态、SSL 要求等;GRANT/REVOKE 才管数据库、表、列级操作权限。
典型误操作:
- 想改密码又顺手加权限,写成:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'xxx' WITH GRANT OPTION;→ 语法错误,WITH GRANT OPTION只属于GRANT - 用
ALTER USER试图给某个库加SELECT权限 → 完全无效,语句能执行但权限没变 - 撤销权限后忘记
GRANT补回其他权限 → 因为GRANT不是“叠加”,而是“声明式覆盖”,没列出来的权限不会保留
真正要调整权限组合,必须严格用 GRANT 和 REVOKE 配合,中间没有模糊地带。











