GRANT ALL PRIVILEGES不含GRANT OPTION,因其仅覆盖DML/DCL类操作权限(如SELECT、INSERT、DROP),而GRANT OPTION是独立的授予权开关,需显式添加WITH GRANT OPTION;MySQL 8.0+还要求先CREATE USER再GRANT,且ALL PRIVILEGES不包含SYSTEM_USER等新增管理权限。

GRANT ALL PRIVILEGES 为什么不含 GRANT OPTION
因为 GRANT ALL PRIVILEGES 在 MySQL 里是“操作权限集合”,不包含“授予权”这个独立开关。它覆盖 SELECT、INSERT、DROP DATABASE 等行为,但 GRANT OPTION 是另一类权限——允许你再用 GRANT 去给别人加权限。两者在权限表中是不同字段:Grant_priv 和 Select_priv 等互不干扰。
常见表现:
- 执行
SHOW GRANTS FOR 'u'@'%'只看到ALL PRIVILEGES,没出现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)。账户创建和权限授予被拆成原子操作,更安全也更明确。
正确流程是:
- 先建户:
CREATE USER 'u'@'%' IDENTIFIED BY 'p' - 再赋权:
GRANT ALL PRIVILEGES ON *.* TO 'u'@'%' WITH GRANT OPTION - 最后刷新(保险起见):
FLUSH PRIVILEGES
漏掉 CREATE USER 或混用旧语法,权限根本不会写入 mysql.user 表。
ALL PRIVILEGES 不等于“所有管理权限”
即使加了 WITH GRANT OPTION,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 依然会拒绝。
权限生效前最容易忽略的三件事
执行完 GRANT 并 FLUSH PRIVILEGES,不代表用户马上有权限。还要确认:
- 用户连接时实际匹配的 host 是什么?
SELECT user(), current_user()—— 如果你GRANT的是'u'@'%',但用户从本地连进来却走的是'u'@'localhost',那权限压根不生效 - MySQL 配置里
bind-address是不是还设成127.0.0.1?这会让@'%'用户无法远程连接 - Linux 防火墙有没有放行
3306?ufw status或firewall-cmd --list-ports看一眼
权限系统本身很细,但真正卡住人的往往不是 SQL 语句,而是 host 匹配、网络通路、配置联动这些“看不见”的环节。


















