应查mysql.user表而非information_schema.user_privileges,因后者仅返回usage权限;需显式查询select_priv等字段并注意host匹配,且权限变更后须flush privileges才生效。

直接查 information_schema.user_privileges 看不到真实全局权限
这个表只返回 USAGE 权限,不管用户实际有没有 SELECT、PROCESS 或 SHUTDOWN 这类全局权限。它本质是“元数据视图”,不映射 mysql.user 表里的具体权限字段,属于设计上的抽象层,不能用于权限审计或故障排查。
真正有效的全局权限查询方式:必须查 mysql.user 表
所有全局权限(如 select_priv、process_priv、super_priv)都以 Y/N 字符串形式存在 mysql.user 表中。你需要显式筛选字段并注意 WHERE 条件的写法:
SELECT user, host, select_priv, insert_priv, process_priv, super_priv FROM mysql.user WHERE user = 'appuser' AND host = 'localhost';- 如果
host是%,记得用单引号包裹:AND host = '%' - 执行前需有
SELECT权限访问mysql库,普通应用账号默认没有,只能由 DBA 或 root 执行 - MySQL 8.0+ 中部分字段名有变化(如
authentication_string替代password),但权限字段命名保持一致
SHOW GRANTS FOR 'u'@'h' 返回的是授权语句,不是原始权限状态
这条命令输出的是“如何用 GRANT 重建当前权限”的逻辑表达,不是底层存储值。它会把多个权限合并成一条语句(比如 GRANT SELECT, INSERT ON *.* TO 'u'@'h'),但无法反映以下真实情况:
- 该用户是否曾被
UPDATE mysql.user SET process_priv = 'Y'直接修改过,而未走 GRANT 流程 - 权限是否已被
REVOKE撤销但缓存未刷新(FLUSH PRIVILEGES未执行) - 是否受角色(role)间接影响——
SHOW GRANTS会列出角色授予的权限,但不会说明来源是角色还是直授
容易被忽略的关键点:权限生效依赖内存加载,不是实时读表
MySQL 启动时把 mysql.user 等权限表加载进内存;运行中修改表后,必须执行 FLUSH PRIVILEGES 才能让新权限对后续连接生效。这意味着:
- 即使你刚
UPDATE mysql.user改了process_priv,不FLUSH就执行SHOW PROCESSLIST,仍看不到效果 -
SELECT查询mysql.user表能立刻看到字段值,但这只是“磁盘状态”,不代表“当前实例行为” - 在主从架构中,
FLUSH PRIVILEGES不会复制到从库,需在从库单独执行(如果从库也启用了权限检查)











