grant all privileges 不含 grant option,因其仅为 dml/dcl 权限集合,不包含授予权;grant option 需显式添加且作用域严格限定于当前授权范围。

GRANT ALL PRIVILEGES 为什么不含 GRANT OPTION
因为 GRANT ALL PRIVILEGES 在 MySQL 权限模型里只是 DML/DCL 类操作权限的集合,不包含“授予权”这个独立开关。它覆盖 SELECT、INSERT、DROP、CREATE 等行为,但 GRANT OPTION 存在于 mysql.user 表的 Grant_priv 字段,和 Select_priv 等字段互不干扰。
常见表现:
-
SHOW GRANTS FOR 'u'@'%'输出里没出现WITH GRANT OPTION - 用户能查、能删库,但执行
GRANT SELECT ON db.* TO 'x'@'%'直接报ERROR 1045 (28000) -
SELECT Grant_priv FROM mysql.user WHERE User='u' AND Host='%'返回N
MySQL 8.0+ 必须先 CREATE USER 再 GRANT
旧写法 GRANT ALL PRIVILEGES ON *.* TO 'u'@'%' IDENTIFIED BY 'p' WITH GRANT OPTION 在 MySQL 8.0+ 会触发 ERROR 1064 (42000) ——语法被彻底移除。账户创建和权限授予被拆成原子操作,底层逻辑是权限信息分散在 mysql.user 等 5 张表中,CREATE USER 负责初始化记录,GRANT 负责填充值。
正确流程只有三步(缺一不可):
- 先建户:
CREATE USER 'u'@'%' IDENTIFIED BY 'p' - 再赋权:
GRANT ALL PRIVILEGES ON *.* TO 'u'@'%' WITH GRANT OPTION - 最后刷新(保险起见):
FLUSH PRIVILEGES
ALL PRIVILEGES 不等于“所有管理权限”
即使加了 WITH GRANT OPTION,GRANT ALL PRIVILEGES ON *.* 仍不包含 MySQL 8.0 新增的高危管理权限,比如 SYSTEM_USER、BACKUP_ADMIN、CLONE_ADMIN、REPLICATION CLIENT。这些权限必须显式追加:
GRANT SYSTEM_USER, REPLICATION CLIENT ON *.* TO 'u'@'%'
否则用户执行 SHOW SLAVE STATUS 或 BACKUP DATABASE 依然被拒绝。而且这些权限不随 ALL PRIVILEGES 自动继承,也不能靠 WITH GRANT OPTION 授出。
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 表的任何权限。跨库、跨权限类型、跨主机的授权都会失败。
真正容易被忽略的是:权限粒度和作用域绑定太紧,稍不注意就变成“看着有权限,实际用不了”。尤其在多租户或分库场景下,ON *.* 的滥用反而比精细授权更难排查问题。











