SHOW GRANTS FOR 报错 Access denied 是因当前用户无权查询他人权限,仅 root 或具 SELECT ON mysql.user 权限者可执行;查自身权限应使用 CURRENT_USER();% 与 localhost 账户权限独立;GRANT 后须 FLUSH PRIVILEGES 生效。

SHOW GRANTS FOR 报错 Access denied for user
你执行 SHOW GRANTS FOR 'user'@'host' 时被拒绝,大概率不是语法问题,而是当前登录用户没权限查别人。MySQL 默认只允许用户查自己的权限(SHOW GRANTS 不带 FOR 时才允许)。
- 必须用
root或拥有SELECT ON mysql.user+SHOW DATABASES权限的账号执行带FOR的语句 - 普通用户即使对自己查,也得加引号:
SHOW GRANTS FOR CURRENT_USER()比SHOW GRANTS FOR 'me'@'%'更可靠 - 如果目标用户不存在,会报错
ERROR 1141 (42000): There is no such grant defined for user ...,不是权限问题,是名字写错了
SHOW GRANTS 返回结果里 % 和 localhost 不等价
MySQL 把 'user'@'%' 和 'user'@'localhost' 当作两个完全独立的账户,权限互不影响。很多线上问题就出在这儿——你以为给 % 授权了,结果应用连的是 localhost,根本没生效。
-
SHOW GRANTS FOR 'app'@'%'和SHOW GRANTS FOR 'app'@'localhost'必须分别执行,不能省略 - 本地命令行连 MySQL 默认走 socket,实际认证用的是
localhost,不是127.0.0.1;想强制走 TCP,得显式加-h 127.0.0.1 - 权限列表里出现
GRANT USAGE ON *.*表示该用户存在但没显式授权,不是漏查,是真的空
GRANT 语句和 SHOW GRANTS 输出不一致?看是否刷权限
执行 GRANT 后立刻 SHOW GRANTS 看不到新权限,通常不是缓存,而是权限表没重载。
- 执行
GRANT后必须跟FLUSH PRIVILEGES,否则权限变更只在内存里,重启 mysqld 会丢失 - 但更推荐直接改
mysql.user表后手动FLUSH PRIVILEGES,避免GRANT语句隐式覆盖已有权限(比如重复GRANT SELECT可能清掉之前给的INSERT) -
SHOW GRANTS显示的是当前生效的权限快照,不反映未提交的事务或未刷入的变更
用 SELECT FROM mysql.tables_priv 查细粒度权限太麻烦
SHOW GRANTS 只显示全局和数据库级权限,表级、列级、存储过程权限不会展开。想确认某用户能不能查某张表,光看它输出不够。
- 表级权限存在
mysql.tables_priv,列级在mysql.columns_priv,但直接查这些表要SELECT ON mysql.*权限,生产环境通常不开 - 更实用的办法:用目标用户身份连上去,执行
SELECT * FROM information_schema.role_table_grants(MySQL 8.0+)或SELECT * FROM information_schema.role_column_grants - 低版本只能靠测试:用该用户执行
EXPLAIN SELECT * FROM db.tbl,如果报ERROR 1142 (42000): SELECT command denied就说明没权限
权限系统里最麻烦的从来不是怎么查,而是“哪个 host 匹配哪条连接”“改完权限到底刷没刷”“USAGE 是不是真没权限”,这些点不盯住,SHOW GRANTS 再准也没用。


















