ALL PRIVILEGES 不包含 CREATE USER 和 GRANT OPTION 等管理权限,需显式授予:GRANT CREATE USER, GRANT OPTION ON . TO 'u'@'%' WITH GRANT OPTION;验证须查 mysql.user 表中 Grant_priv 和 Create_user_priv 字段是否为 'Y'。

ALL PRIVILEGES 不等于 GRANT 权限,缺了 WITH GRANT OPTION 就没法创建用户、授权别人、甚至执行 CREATE USER。
为什么 GRANT ALL PRIVILEGES ON *.* TO 'u'@'%' 之后还报 Access denied?
因为 MySQL 的权限是分层的:ALL PRIVILEGES 只覆盖 DML/DCL 类操作(如 SELECT、INSERT、DROP DATABASE),但不自动包含 CREATE USER、GRANT OPTION、PROXY 等管理类权限。这些必须显式授予。
常见现象:
- 执行
CREATE USER 'x'@'%' IDENTIFIED BY 'p';报错ERROR 1227 (42000): Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation - 执行
GRANT SELECT ON db.* TO 'y'@'%';报错ERROR 1045 (28000): Access denied for user ... (using password: YES),即使自己有ALL PRIVILEGES -
SHOW GRANTS FOR 'u'@'%';返回只有USAGE或不含GRANT OPTION
GRANT OPTION 和 CREATE USER 权限到底要怎么给?
MySQL 5.7 要求这两项必须单独或组合授予,不能靠 ALL PRIVILEGES 带出来:
-
GRANT OPTION是「授予权」——允许该用户再用GRANT给别人加权限 -
CREATE USER是「建户权」——允许执行CREATE USER/DROP USER/RENAME USER - 两者常一起给:
GRANT CREATE USER, GRANT OPTION ON *.* TO 'u'@'%' WITH GRANT OPTION; - 注意:末尾的
WITH GRANT OPTION是给当前用户自己加「授予权」,不是给目标用户的;前面的GRANT OPTION是具体权限名,必须写在GRANT列表里
检查权限是否真生效的三个关键命令
别只信 SHOW GRANTS 输出,它可能缓存或省略隐式权限。实操中务必交叉验证:
- 查用户是否有
Grant_priv字段:SELECT User, Host, Grant_priv, Create_user_priv FROM mysql.user WHERE User = 'u' AND Host = '%';—— 这是底层开关,Grant_priv='Y'才真能GRANT - 查是否被更细粒度权限覆盖:
SELECT * FROM mysql.db WHERE User = 'u' AND Host = '%' AND Db = 'mysql';—— 如果db表里对mysql库显式设了空权限,会压制全局权限 - 验证能否实际执行:
SELECT CURRENT_USER(); GRANT SELECT ON test.* TO 'u'@'%';—— 如果失败,说明GRANT OPTION没生效,不是语法问题而是权限缺失
MySQL 5.7 和 8.0 在这方面的关键差异
虽然你问的是 5.7,但工具或脚本混用时容易踩坑:
- 5.7 支持
GRANT ... IDENTIFIED BY一步建户授权,8.0 已废弃,必须先CREATE USER再GRANT - 5.7 中
GRANT ALL PRIVILEGES ON *.* TO 'u'@'%'不带WITH GRANT OPTION就真的没有授予权;8.0 更严格,连CREATE USER都必须单独列在GRANT语句里 -
mysqldump --no-data --skip-triggers导出的权限语句在 5.7 可能含GRANT USAGE占位符,还原到 8.0 会静默失败,看不出错在哪
真正卡住的地方往往不是语法写错,而是 mysql.user 表里 Grant_priv 和 Create_user_priv 这两个字段值为 N,而你只盯着 SHOW GRANTS 输出看。











