mysql 8.0 的 grant 语句不再支持直接创建用户,必须先用 create user 显式建用户并设置密码,再用 grant 赋权;grant 后权限立即生效,无需 flush privileges。

MySQL 8.0 的 GRANT 语句不再支持直接创建用户
这是最常见报错根源:你在一条 GRANT 语句里同时指定新用户名和权限,比如:
GRANT SELECT ON mydb.* TO 'newuser'@'localhost' IDENTIFIED BY 'pwd123';
MySQL 8.0 默认禁用了这种“隐式建用户”写法(sql_mode 中含 NO_AUTO_CREATE_USER,且该模式已彻底移除)。执行会直接报错:ERROR 1064 (42000): You have an error in your SQL syntax。
- 必须先用
CREATE USER显式建用户,再用GRANT赋权 - 密码必须通过
IDENTIFIED WITH或IDENTIFIED BY在CREATE USER中设置,不能塞进GRANT - 如果用户已存在,
CREATE USER会报错;加IF NOT EXISTS可避免
GRANT 后必须跟 FLUSH PRIVILEGES 吗?
不需要。MySQL 8.0 中 GRANT 执行成功后权限立即生效,FLUSH PRIVILEGES 不但多余,还可能掩盖问题——比如你误以为没生效而反复刷,实则权限早已加载。
- 仅当你手动修改了
mysql.user等系统表(不推荐)后才需FLUSH PRIVILEGES - 执行
GRANT后可立刻用SHOW GRANTS FOR 'user'@'host';验证结果 - 如果验证无权限,说明
GRANT本身没执行成功(比如语法错、用户不存在、当前账号无GRANT OPTION)
账户名带特殊字符或大小写时容易出错
MySQL 8.0 对用户名和主机名的匹配更严格,引号使用不当会直接导致语法错误或权限错配。
- 用户名和主机名必须用单引号
'包裹,不能用双引号或反引号 - 例如
GRANT SELECT ON *.* TO `admin`@`%`;是错的,应写成GRANT SELECT ON *.* TO 'admin'@'%'; - 主机名用
%表示任意主机,但'%'@'localhost'和'%'@'%'是两个完全不同的账户 - Linux 下用户名区分大小写,
'User'≠'user';建议统一小写避免混淆
权限层级和对象名不能省略数据库名
在 MySQL 8.0 中,对表级或列级授权时,数据库名不可省略(哪怕当前已 USE db_name),否则报语法错误。
- 错:
GRANT INSERT(col1) ON table1 TO 'u'@'h';(缺数据库名) - 对:
GRANT INSERT(col1) ON mydb.table1 TO 'u'@'h'; - 全局权限如
PROCESS、RELOAD必须写成ON *.*,不能只写ON * - 若要授所有数据库的所有权限,必须写
ON *.*,不是ON *.或空着
实际操作中最容易卡住的,是把 5.7 的习惯直接套到 8.0 上——尤其是那条带 IDENTIFIED BY 的单行 GRANT。它在 8.0 里不是“不推荐”,而是根本解析不过。











