MySQL 5.7及之前版本中,mysql.user表的权限列均为\_priv结尾的布尔字段(如Select_priv、Super_priv等),每个字段对应一种全局权限;MySQL 8.0+中这些字段已废弃且恒为'N',实际权限由角色和mysql.global_grants等新机制管理。

mysql.user 表里哪些字段是权限列
MySQL 5.7 及之前版本中,mysql.user 表的权限是以单个布尔字段形式存在的(如 Select_priv、Insert_priv),每个字段对应一种全局权限;MySQL 8.0 起改用角色 + mysql.global_grants,但 mysql.user 仍保留部分兼容字段(如 Account_locked、password_expired),而绝大多数权限已移出该表。
所以查“每一列代表什么权限”,得先确认你的 MySQL 版本:
- MySQL 5.7 或更早:直接看
mysql.user字段,权限字段名基本是*_priv形式 - MySQL 8.0+:
mysql.user中的*_priv字段已废弃(值恒为N),真实权限在mysql.role_edges、mysql.default_roles和INFORMATION_SCHEMA.APPLICABLE_ROLES等处管理
MySQL 5.7 查看 user 表权限字段含义的实操方法
最直接的方式是查官方文档字段定义,但现场快速确认可用以下命令:
DESCRIBE mysql.user;
重点关注字段名含 _priv 的列,例如:
-
Select_priv:是否允许执行SELECT(全局级别) -
Super_priv:是否允许执行KILL、SET GLOBAL、修改其他用户会话等高危操作 -
Grant_priv:是否允许给其他用户授予权限(不等于自己有对应权限) -
Repl_slave_priv:是否能作为复制从库连接主库(即CHANGE MASTER TO权限) -
Execute_priv:是否允许执行存储过程(注意:不是调用,而是创建/修改)
注意:max_questions、max_updates 这类是资源限制字段,不属于权限范畴;ssl_type、plugin 属于认证相关,也不控制访问能力。
MySQL 8.0+ 为什么 SELECT * FROM mysql.user 看不到有效权限
因为从 8.0 开始,MySQL 把权限系统重构为基于角色的模型,mysql.user 表中所有 *_priv 字段被设为只读且默认 'N',实际权限由以下机制控制:
- 用户拥有的角色记录在
mysql.role_edges(谁属于哪个角色) - 角色本身的权限在
mysql.role_tables_priv、mysql.role_columns_priv等专用表中 - 全局权限统一存于
mysql.global_grants(MySQL 8.0.16+ 引入) - 查询当前用户实际拥有的权限,应使用
SHOW GRANTS FOR 'u'@'h';,而非查mysql.user
直接 SELECT mysql.user 会看到一堆 'N',这不是数据异常,是设计如此——它已退化为账户元信息表(密码、锁定状态、过期时间等)。
容易被忽略的关键点
权限判断不是只看 mysql.user。MySQL 实际检查权限时是分层匹配的:
- 先查
mysql.user(全局)→ 再查mysql.db(库级)→ 再查mysql.tables_priv(表级)→ 最后到列级、程序级 - 哪怕
mysql.user.Select_priv = 'Y',若mysql.db中对应库的Select_priv = 'N',该用户对该库仍无查询权 -
SHOW GRANTS输出的是最终生效权限,是各层级叠加 + 拒绝项(DENY)计算后的结果,比查表更可靠
别只盯着 mysql.user 硬解字段,先 SHOW GRANTS FOR CURRENT_USER();,再按需溯源,效率更高,也更贴近真实行为。


















