show grants 是查看当前用户权限最直接可靠的方式,执行后显示 grant 语句中的权限列表、作用范围及 'user'@'host' 标识;查他人权限须严格匹配完整用户名和主机名,且不可依赖 mysql.user 表——因其仅存全局权限,不涵盖库表级及角色继承权限。

查当前在线用户用 SHOW PROCESSLIST,但权限信息不在里面
直接执行 SHOW PROCESSLIST 只能看到谁连着、在执行什么 SQL、状态如何,不包含权限信息。MySQL 的权限是静态配置在系统表里的,不是按连接动态计算的。所以“在线用户的权限状态”本质是:查出当前活跃连接对应的账号,再查这个账号在 mysql.user 和相关授权表里的权限记录。
先确认哪些用户正在连接:用 SELECT USER(), CURRENT_USER() 和 information_schema.PROCESSLIST
USER() 返回客户端声明的身份(可能带 host),CURRENT_USER() 才是 MySQL 实际认证后匹配到的账号(即真正生效权限的依据)。要查所有在线连接对应的真实账号,得查 information_schema.PROCESSLIST:
SELECT DISTINCT CONCAT('''', user, '''@''', host, '''') AS account
FROM information_schema.PROCESSLIST
WHERE user != 'system user';
注意:host 字段可能被 DNS 解析成 IP 或域名,和 mysql.user 里存的 pattern(如 '%'、'192.168.%.%'、'localhost')不一定字面一致,匹配靠 MySQL 内部通配逻辑,不能简单用 = 对比。
查权限要用 SHOW GRANTS FOR ...,别直接查 mysql.user
mysql.user 表只存全局权限(如 SELECT_priv),而数据库级、表级、列级权限分散在 mysql.db、mysql.tables_priv 等表里,手动 JOIN 极易漏项或误判。正确做法是逐个账号执行:
- 对每个从
PROCESSLIST提取的账号,运行SHOW GRANTS FOR 'user'@'host' - 如果账号含特殊字符(如
@、空格),必须用单引号包裹,否则语法错误 -
SHOW GRANTS输出的是可执行的 SQL 语句,能清晰看到权限范围(比如GRANT SELECT ON `test`.* TO 'u1'@'%'),比查系统表直观得多 - 注意:需要
SELECT权限才能查information_schema.PROCESSLIST,需要SELECT权限才能查mysql.user,但执行SHOW GRANTS FOR需要SELECT权限或GRANT OPTION—— 普通用户查自己账号可以,查别人会报错Access denied; you need (at least one of) the SELECT privilege(s) for the mysql database
自动化脚本要注意权限边界和 host 匹配问题
写脚本批量查时,常见坑是:
- 把
PROCESSLIST.host直接拼进SHOW GRANTS FOR 'u'@'h',但实际认证用的是CURRENT_USER(),而CURRENT_USER()的 host 可能被 MySQL 规范化(比如127.0.0.1→localhost),导致查不到 - 用 root 查没问题,但用普通账号运行脚本,
SHOW GRANTS FOR对非自身账号会失败,脚本需加异常捕获 -
SHOW GRANTS不显示角色(role)继承的权限,如果启用了 roles,还得额外查mysql.role_edges和对应角色的权限 - 权限生效有缓存:改完
GRANT后没执行FLUSH PRIVILEGES(其实一般不用,除非直改系统表),新权限可能未加载,查出来和实际不符
真要拿到“当前连接实际能做什么”,最稳妥的方式是让应用层用该连接自己执行 SELECT * FROM mysql.user WHERE User=USER() AND Host=SUBSTRING_INDEX(USER(),'@',-1) 类似语句做权限探测——但这只覆盖全局权限,细粒度操作仍得靠 SHOW GRANTS 结合业务场景推断。











