SHOW GRANTS(不带FOR)显示当前连接所用账号的权限;若启用role需查INFORMATION_SCHEMA.APPLICABLE_ROLES和ENABLED_ROLES;动态权限需查PERFORMANCE_SCHEMA.SESSION_VARIABLES;表级权限查TABLE_PRIVILEGES,空字符串表示所有表;WITH GRANT OPTION允许转授权限;权限缓存需新连接验证。

SHOW GRANTS FOR 当前用户不生效?先确认你是谁
MySQL 的 SHOW GRANTS FOR 查的是「指定用户账号」的权限,不是当前登录用户的权限。如果你用 root@localhost 登录,但执行 SHOW GRANTS FOR 'alice'@'%',看到的当然是 alice 的权限,和你当前能做什么无关。
真正想看「自己此刻能干什么」,应该查当前会话实际生效的权限组合——这取决于:你登录时使用的账号 + 当前数据库上下文 + 是否有激活的 roles。
- 最直接的方式是运行
SHOW GRANTS(不带FOR),它默认显示当前用户连接所用账号的权限 - 如果用了 role(MySQL 8.0+),还要额外查
SELECT * FROM INFORMATION_SCHEMA.APPLICABLE_ROLES和SELECT * FROM INFORMATION_SCHEMA.ENABLED_ROLES - 注意:
SHOW GRANTS不反映动态权限(如CONNECTION_ADMIN)是否已启用,得看SELECT * FROM PERFORMANCE_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME = 'activate_all_roles_on_login'
用 INFORMATION_SCHEMA 查询权限比 SHOW GRANTS 更细,但容易漏表级权限
INFORMATION_SCHEMA.SCHEMA_PRIVILEGES、TABLE_PRIVILEGES、COLUMN_PRIVILEGES 这些系统表确实能查到更颗粒度的授权记录,比如某用户对某个库某张表的具体操作权限。但它们只存显式授予的权限,不包含继承自角色、也不反映全局权限(如 PROCESS、SUPER)。
-
SCHEMA_PRIVILEGES里GRANTEE字段格式是'user'@'host',注意单引号和 @ 符号都要匹配,别漏掉引号直接写alice@% - 查表级权限时,
TABLE_PRIVILEGES的TABLE_SCHEMA是库名,TABLE_NAME是表名,但空字符串表示「所有表」,不是 NULL —— 别用IS NULL去过滤 - 这些表不包含列级权限是否被显式拒绝(DENY),MySQL 目前不支持 DENY 语义,所以查不到「禁止」动作
SHOW GRANTS 输出结果里出现 WITH GRANT OPTION 意味着什么
如果 SHOW GRANTS 返回的某条授权语句末尾有 WITH GRANT OPTION,说明这个用户不仅能执行对应操作,还能把该权限再授给其他人。这不是装饰,是真实的能力开关。
- 哪怕你只有
SELECT权限,只要带WITH GRANT OPTION,就能执行GRANT SELECT ON db.tbl TO 'other'@'host' - 撤销权限时,
REVOKE默认不连带收回GRANT OPTION,必须显式加上GRANT OPTION FOR才能清除它 - MySQL 8.0.16+ 开始,
GRANT OPTION可以单独授予/回收,但老版本只能随具体权限一起操作,这点容易误判权限边界
权限缓存导致刚授权却查不到?别忘了 FLUSH PRIVILEGES
MySQL 在内存中缓存权限数据,当你用 GRANT 或 REVOKE 修改后,新连接会立即看到变更,但已有连接不会自动刷新——它仍按旧权限运行,直到重连或手动刷新。
- 大多数情况下不用手动
FLUSH PRIVILEGES,因为GRANT语句本身就会触发内存更新;但如果你是直接改了mysql.user表(比如用UPDATE),就必须执行它 -
FLUSH PRIVILEGES是全局操作,会影响所有连接,生产环境慎用,尤其高并发时可能短暂阻塞权限检查 - 验证是否生效,最稳妥的方式是新开一个客户端连接再跑
SHOW GRANTS,而不是在原连接里反复试
权限这事没法靠一次查询就看清全貌,特别是开了 role、用了 proxy user、或者权限来自多个 host 匹配规则的时候。最容易被忽略的是:当前连接看到的权限,未必等于你下次登录时拿到的权限。










