show grants是唯一能查看完整生效权限的命令,可输出真实可复用的授权语句;它默认查current_user()、查他人须严格指定'user'@'host'、不显示角色继承权限需加using子句、动态权限和列级权限仅此可见。

SHOW GRANTS 是唯一能看全权限的命令
直接查 mysql.user 或其他系统表,永远漏权限——列级、存储过程级、角色继承来的、动态权限(如 BACKUP_ADMIN)全都不在表里。只有 SHOW GRANTS 能拼出真实生效的完整授权语句,所见即所得。
常见错误是只执行 SHOW GRANTS FOR 'user',结果报错 ERROR 1141 (42000):MySQL 要求必须带主机名,哪怕你记得是 '%',也得写成 'user'@'%'。不加 @'host' 就等于查一个根本不存在的账号。
-
SHOW GRANTS不带参数 → 查当前登录用户权限,连上就能用,不需要任何额外权限 -
SHOW GRANTS FOR CURRENT_USER()→ 效果一样,更明确表达“当前会话用户” -
SHOW GRANTS FOR 'app'@'10.20.30.%'→ 必须和授权时的 host 完全一致,'app'@'%'和'app'@'localhost'是两个不同账号 - 如果用户通过角色获得权限,
SHOW GRANTS默认不展开,得加USING 'role_name'才能看到继承来的权限
导出权限到 SQL 文件别用复制粘贴
图形化工具里右键复制 SHOW GRANTS 输出,容易丢换行、吃掉反引号、吞掉单引号里的转义字符——尤其当权限语句含数据库名带下划线或特殊符号时,粘贴回来的语句大概率无法执行。
最稳的方式是命令行重定向:
mysql -u root -p -e "SHOW GRANTS FOR 'app_user'@'10.20.30.%';" > app_user_grants.sql
注意三点:
- 必须用双引号包裹整个 SQL,否则 shell 会提前解析
@和; - 输出文件里每条
GRANT语句自带换行和分号,可直接用于恢复或审计 - 如果目标用户权限涉及多个 host(比如
'app'@'10.20.30.%'和'app'@'192.168.1.5'),得分别导出,不能靠模糊匹配
查不到权限?先确认你有没有查的资格
SHOW GRANTS FOR 'xxx'@'yyy' 不是所有人都能跑。如果你不是 root 或没被授予 SELECT 权限访问 mysql 库,就会卡在 Access denied ——这不是权限没配好,是你没权限看别人权限。
这时候有两个选择:
- 换高权限账号登录再查(推荐)
- 退而求其次,用
SELECT查系统表,但得知道查哪张表、查什么字段:
全局权限 →SELECT User, Host, Select_priv, Insert_priv, Super_priv FROM mysql.user WHERE User='xxx' AND Host='yyy';
库级权限 →SELECT Db, Select_priv, Insert_priv FROM mysql.db WHERE User='xxx' AND Host='yyy';
表级权限 →SELECT Table_schema, Table_name, Table_priv FROM mysql.tables_priv WHERE User='xxx' AND Host='yyy'; - MySQL 8.0+ 的动态权限(如
CLONE_ADMIN)不会出现在这些表里,只能靠SHOW GRANTS或查mysql.role_edges+mysql.role_routine_grants
看到 GRANT USAGE ON *.* 别慌,那是真没权限
SHOW GRANTS 输出第一行常是 GRANT USAGE ON *.* TO 'xxx'@'yyy',这不是 bug,而是 MySQL 的占位符:USAGE 表示该账号只允许连接、能访问 information_schema,但没被显式授予任何操作权限(SELECT/INSERT/CREATE 等全为 N)。
这时候别急着翻表找原因,先确认两件事:
- 是否真的执行过
GRANT语句?没授过就是真没权限 - 是否授了权限但忘了
FLUSH PRIVILEGES?8.0+ 一般不用刷,但旧版本或某些配置下可能延迟生效 - 是否授的是角色权限,但没激活角色?
SET ROLE 'app_role';才能生效,否则SHOW GRANTS默认不显示
真正麻烦的是权限嵌套太深:角色 A 授给角色 B,B 再授给用户 C,中间任意一层没激活或没 WITH ADMIN OPTION,都会断链。这种时候光看 SHOW GRANTS 不够,得顺藤摸瓜查 mysql.role_edges。











