grant all privileges本身不含grant option,必须显式添加with grant option才能转授;mysql 8.0+需先create user再grant,且grant option仅在其权限作用域内生效。

GRANT ALL PRIVILEGES 本身不含 GRANT OPTION
执行 GRANT ALL PRIVILEGES ON *.* TO 'u'@'%' 后,用户确实能执行 SELECT/INSERT/UPDATE/DELETE/CREATE/DROP 等操作,但无法再把任何权限授予别人——因为 GRANT OPTION 是独立开关,不包含在 ALL PRIVILEGES 里。这是 MySQL 的权限模型设计,不是 bug。
常见错误现象:
-
SHOW GRANTS FOR 'u'@'%'输出里没有WITH GRANT OPTION - 该用户执行
GRANT SELECT ON db1.* TO 'v'@'%'直接报错ERROR 1045 (28000): Access denied
解决办法只有一条:显式加 WITH GRANT OPTION:
GRANT ALL PRIVILEGES ON *.* TO 'u'@'%' WITH GRANT OPTION;
MySQL 8.0+ 必须先 CREATE USER 再 GRANT
在 MySQL 8.0 及以上版本,GRANT ... IDENTIFIED BY 语法已被移除。如果你沿用老写法:
GRANT ALL PRIVILEGES ON *.* TO 'u'@'%' IDENTIFIED BY 'pwd' WITH GRANT OPTION;
会立刻触发 ERROR 1064 (42000),提示语法错误。
必须拆成两步:
- 先创建用户:
CREATE USER 'u'@'%' IDENTIFIED BY 'pwd'; - 再赋权:
GRANT ALL PRIVILEGES ON *.* TO 'u'@'%' WITH GRANT OPTION; - 最后建议执行:
FLUSH PRIVILEGES;(尤其跨客户端操作后)
如果用户已存在,CREATE USER 会失败,此时改用:ALTER USER 'u'@'%' IDENTIFIED BY 'newpwd';
ALL PRIVILEGES 不等于“所有管理权限”
即使你执行了 GRANT ALL PRIVILEGES ON *.* TO 'u'@'%' WITH GRANT OPTION;,该用户依然不能执行某些高危管理操作,比如:
-
SHOW MASTER STATUS(需要REPLICATION CLIENT) -
BACKUP DATABASE(需要BACKUP_ADMIN) -
CLONE INSTANCE(需要CLONE_ADMIN) - 切换用户身份(需要
SYSTEM_USER)
这些是 MySQL 8.0 新增的细粒度管理权限,不会被 ALL PRIVILEGES 覆盖。必须单独追加:
GRANT REPLICATION CLIENT, BACKUP_ADMIN ON *.* TO 'u'@'%';
权限作用域决定 GRANT OPTION 的实际能力
WITH GRANT OPTION 不是全局通行证,它严格绑定在当前 GRANT 语句的作用域上。例如:
GRANT SELECT, INSERT ON app_db.* TO 'dev'@'localhost' WITH GRANT OPTION;
那么 dev 只能将 SELECT 和 INSERT 授予别人,且仅限于 app_db 下的表;他不能授 UPDATE,也不能授 mysql.user 表的权限。
想让某用户能授予任意权限?必须给:
-
ALL PRIVILEGES ON *.*(覆盖所有数据库和表) -
且
WITH GRANT OPTION(缺一不可)
另外注意:'u'@'localhost' 和 'u'@'%' 是两个完全独立的账号,权限不互通;SELECT user(), current_user(); 返回的 host 必须和你 GRANT 的完全一致,否则权限根本不会匹配。











