文章来源:数据库内核月报 2024/01 - MySQL 权限管理

MySQL 权限简介

MySQL 账号权限(本文聚焦静态权限)决定了账户可执行的操作。日常常见授权方式(如 db 级别 select、table 级别 update)比较直观,但底层权限划分与校验实现更值得系统梳理。

权限层级分类

MySQL 静态权限按控制范围可分为:

  • global
  • database
  • table
  • column
  • routines

权限层级范围示意图

授权时有两个关键规则:

  1. 高层级授权会向下继承
  2. 某些权限仅能在特定层级授权(例如 create user 只能 global)

示例(非法层级授权会报错):

mysql> grant create user on db1.* to u1;
ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES

mysql> grant create routine on db1.t to u1;
ERROR 1144 (42000): Illegal GRANT/REVOKE command

mysql> grant update(a) on db1.* to u1;
ERROR 1144 (42000): Illegal GRANT/REVOKE command

权限存储

不同层级授权会落到不同系统表:

  • global -> mysql.user
  • db -> mysql.db
  • table -> mysql.tables_priv
  • column -> mysql.columns_priv

权限变更本质上就是更新这些系统表中的记录。

静态权限与控制范围

例如 mysql.user 表结构如下:

mysql.user 表结构

权限变化示例:

无权限状态:

无权限状态

授予 global select 后:

global select 权限

授予列级 update 后:

列级 update 权限

权限更新流程

通过 GRANT/REVOKE 更新权限时,可以概括为两步:

  1. 解析并确定本次要更新的权限位
  2. 根据授权层级写入对应权限表

权限位表示

MySQL 使用位图表示权限:

#define SELECT_ACL   (1L << 0)
#define INSERT_ACL   (1L << 1)
#define UPDATE_ACL   (1L << 2)
#define DELETE_ACL   (1L << 3)
#define CREATE_ACL   (1L << 4)
#define DROP_ACL     (1L << 5)
#define RELOAD_ACL   (1L << 6)
#define SHUTDOWN_ACL (1L << 7)
#define PROCESS_ACL  (1L << 8)
#define FILE_ACL     (1L << 9)

授权层级合法性校验

权限层级匹配在两个阶段检查:

  1. 语法解析阶段先做早期拦截
  2. mysql_grant 执行阶段再做严格层级校验

其中 DB 级授权会检查权限是否属于 DB_ACLS,不匹配会报 DB GRANT and GLOBAL PRIVILEGES 错误。

权限认证流程(以 SELECT 为例)

执行 SELECT 时会在语义检查阶段进行权限校验,核心链路是:

  1. check_access:先看 user/db 层权限
  2. check_grant:不足再看 table/column 层权限
  3. 合并权限后,在字段解析阶段逐列校验

示例:

create table t (a int, b int);
grant select(a) on db1.t to u1;
select a from t;

此场景下,列级权限需要在后续列解析阶段继续校验,最终在字段处理逻辑中判定当前列是否可访问。

总结

MySQL 权限体系的核心可以理解为:

  • 权限模型:分层 + 位图
  • 权限更新:语法解析 + 层级落表
  • 权限认证:按 user -> db -> table -> column 逐层补全与校验

理解这三层结构后,排查授权异常和权限报错会高效很多。

参考