查 grant_priv 字段仅反映用户是否拥有全局 grant option,不能准确判断其实际授予权限;应使用 show grants for 'user'@'host' 查看是否含 with grant option,并执行 flush privileges 生效。

查 Grant_priv 字段前先确认你真需要它
直接查 mysql.user 表的 Grant_priv 字段,只能告诉你“这个用户有没有被授予 GRANT OPTION”,不是“能不能执行 GRANT”的全部依据。MySQL 8.0+ 引入角色后,如果用户被赋予了带 GRANT OPTION 的角色但没激活(比如没执行 SET ROLE 'admin'),Grant_priv='Y' 仍可能为 'N',而实际权限却来自角色——此时查字段会漏判。
SELECT User, Host, Grant_priv FROM mysql.user WHERE Grant_priv = 'Y' 的坑
这条语句看似直白,但有三个关键限制:
- 必须用具备
SELECT权限访问mysql库的账号执行,普通应用账号通常无此权限,会报Access denied -
Grant_priv是全局权限字段,只反映GRANT OPTION ON *.*,不包含数据库级或表级的GRANT OPTION(如GRANT SELECT ON db1.* TO ... WITH GRANT OPTION) - 结果里
Host值是真实存储值,'localhost'和'127.0.0.1'被视为不同用户,别指望模糊匹配
比查字段更可靠:用 SHOW GRANTS 反推
真正想确认某用户能否给别人授权,应该看它的 SHOW GRANTS 输出里是否含 WITH GRANT OPTION:
- 对当前用户:
SHOW GRANTS;—— 找任意一行末尾带WITH GRANT OPTION的语句 - 对其他用户:
SHOW GRANTS FOR 'u1'@'192.168.%';—— 注意必须写全@'host',否则报错ERROR 1141 - 如果输出里有
GRANT ALL PRIVILEGES ON *.* TO ... WITH GRANT OPTION,说明有全局授予权;如果是GRANT SELECT ON app.* TO ... WITH GRANT OPTION,则仅限该库
查完别忘了 FLUSH PRIVILEGES
手动更新过 mysql.user 表(比如用 UPDATE mysql.user SET Grant_priv='Y' WHERE User='u1'),或者用 GRANT ... WITH GRANT OPTION 授权后,新权限不会自动生效。MySQL 把权限缓存在内存里,必须显式执行:
FLUSH PRIVILEGES;
否则新连接看不到变更,已存在的连接也不会刷新权限状态——这点在调试时最容易卡住,以为授权失败,其实是忘了刷缓存。











