直接查 mysql.user 表看不到完整权限,因其仅存全局权限,而库、表、列级权限分散在 mysql.db、mysql.tables_priv 等表中;show grants 动态合成全层级权限,更可靠。
直接查 mysql.user 表看不到完整权限?
因为 mysql 8.0+ 的权限模型变了,mysql.user 只存全局级权限(如 select_priv),而数据库、表、列级权限分散在 mysql.db、mysql.tables_priv、mysql.columns_priv 等表里。phpmyadmin 默认只展示 mysql.user,不拼接关联,所以你看到的“权限”只是冰山一角。
实操建议:
- 在 phpMyAdmin 的 SQL 标签页中,手动执行多表 JOIN 查询,例如查某用户
'app_user'@'localhost'的所有显式授权:
SELECT u.User, u.Host, u.Select_priv, u.Insert_priv, u.Update_priv, db.Db, db.Select_priv AS db_select, db.Insert_priv AS db_insert, tp.Table_name, tp.Table_priv FROM mysql.user u LEFT JOIN mysql.db db ON u.User = db.User AND u.Host = db.Host LEFT JOIN mysql.tables_priv tp ON u.User = tp.User AND u.Host = tp.Host AND db.Db = tp.Db WHERE u.User = 'app_user' AND u.Host = 'localhost';
mysql.tables_priv.Table_priv 存的是逗号分隔字符串(如 'Select,Insert'),不是布尔值;解析需后处理或用 FIND_IN_SET('Select', tp.Table_priv)
Grant_priv,8.0 新增 Account_locked)phpMyAdmin 里为什么 SHOW GRANTS 比查系统表更可靠?
SHOW GRANTS FOR 'user'@'host' 是 MySQL 服务端动态合成的结果,它把所有层级权限(global + db + table + column + procedure)合并成可执行的 GRANT 语句,绕过了手动 JOIN 多张表的麻烦和字段兼容性问题。
实操建议:
- 在 phpMyAdmin 的 SQL 标签页中直接运行:
SHOW GRANTS FOR 'app_user'@'localhost';
- 如果提示
Access denied,说明当前登录账号没权限查其他用户——这不是 phpMyAdmin 限制,是 MySQL 权限体系本身要求:必须有SELECT权限在mysql库,或拥有SELECT权限在任意库(MySQL 8.0.17+ 还要SYSTEM_USER或APPLICATION_PASSWORD_ADMIN特权) - 输出结果里带
WITH GRANT OPTION的行,表示该用户能转授对应权限;但不会显示被授予者是谁——这部分信息不在任何系统表里持久化,只存在于运行时授权链中
查权限树时遇到 ERROR 1142 (42000): SELECT command denied
这是最常卡住的地方:你登录 phpMyAdmin 用的账号,根本没被允许读 mysql 系统库。不是配置错了,是 MySQL 故意这么设计的——系统表默认只对 root 或显式授权过的账号开放。
实操建议:
- 先确认当前用户权限:
SELECT CURRENT_USER(), USER();
——注意CURRENT_USER()是认证用户(实际生效的),USER()是连接时声明的(可能被 proxy 用户覆盖) - 检查是否具备
mysql库访问权:SHOW GRANTS;
,看输出里有没有GRANT SELECT ON mysql.*或类似项 - 如果没有,唯一办法是换一个有
SELECT权限在mysql库的账号登录 phpMyAdmin;或者让 DBA 执行:GRANT SELECT ON mysql.* TO 'your_user'@'host'; FLUSH PRIVILEGES;
- 别试图用 phpMyAdmin 的“权限”功能页绕过——它底层也是查
mysql表,同样会触发这个错误
MySQL 8.0+ 的角色(ROLE)权限怎么查?
角色权限不存于 mysql.user,也不出现在 SHOW GRANTS 的主输出里。它被拆成两部分:角色定义(mysql.role_edges)和角色拥有的权限(仍走 mysql.db 等表),但普通用户查不到角色定义表,除非有 SELECT 权限在 mysql 库。
实操建议:
- 查某用户被赋予了哪些角色:
SELECT FROM_USER, TO_USER, USING FROM mysql.role_edges WHERE FROM_USER = 'app_user' AND FROM_HOST = 'localhost';
- 查某个角色本身有哪些权限:
SHOW GRANTS FOR 'my_role'@'%';
(注意角色名也要带 host,即使它是'%') - 角色权限不会自动合并进用户的
SHOW GRANTS输出,除非你显式执行SET ROLE my_role;后再查——但 phpMyAdmin 不支持会话级SET ROLE的持久化,每次执行 SQL 都是新会话 - 如果用户被设为
DEFAULT ROLE,那登录后自动激活;但 phpMyAdmin 的连接池机制可能复用连接,导致角色状态不一致——这时查到的权限可能是上一个用户的残留
权限树本质是动态计算结果,不是一张静态表。想靠一次查询看清全貌,得同时满足三件事:账号有足够系统表读权限、MySQL 版本字段兼容、角色与用户权限链没被连接复用污染。漏掉任一环,看到的都是残缺快照。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










