MySQL动态权限是8.0.16起引入的运行时注册、全局生效的管理权限,不存于系统表,不可被GRANT ALL包含,需显式授予如BACKUP_ADMIN等,且不作用于具体库表。

什么是 MySQL 动态权限(Dynamic Privileges)
MySQL 8.0.16 起引入了动态权限,它和传统静态权限(如 SELECT、INSERT)不同:不存于 mysql.user 等系统表中,而是由服务器在运行时注册、按需启用,主要用于细粒度管控高危操作(比如备份、审计、复制控制),且**不能被 GRANT ALL 自动包含**。
常见动态权限包括:BACKUP_ADMIN、CLONE_ADMIN、REPLICATION_APPLIER、AUDIT_ADMIN、PERSIST_RO_VARIABLES_ADMIN 等。它们不作用于数据库或表,只控制「能不能执行某个管理动作」。
怎么授予/回收动态权限
必须用 GRANT/REVOKE 显式操作,语法和静态权限一致,但**不能带对象(即不能写 ON db.*)** —— 动态权限是全局的,只能作用于 *.* 或省略(MySQL 8.0.21+ 支持省略)。
- 授予:
GRANT BACKUP_ADMIN ON *.* TO 'bkp_user'@'localhost'; - 回收:
REVOKE BACKUP_ADMIN ON *.* FROM 'bkp_user'@'localhost'; - 查看用户已拥有的动态权限:
SHOW GRANTS FOR 'bkp_user'@'localhost';(会明确列出BACKUP_ADMIN这类条目) - 查看当前实例支持哪些动态权限:
SELECT * FROM information_schema.APPLICABLE_ROLES WHERE IS_GRANTABLE = 'YES';或查performance_schema.global_variables中相关开关
为什么不能用 GRANT ALL PRIVILEGES 授予动态权限
因为 GRANT ALL PRIVILEGES 只覆盖「静态权限集合」,而动态权限是独立注册的模块。即使你给用户赋了 ALL PRIVILEGES ON *.*,BACKUP_ADMIN 这类权限依然不会生效——这是设计使然,不是 bug。
容易踩的坑:
- 误以为 root 用户天然拥有所有动态权限 → 实际上 root 也需显式授予(除非初始化时默认开启)
- 用旧版客户端(如 MySQL 5.7 客户端连 8.0+ 服务端)执行
SHOW GRANTS,可能截断或忽略动态权限显示 - 在脚本中批量授权时硬编码
GRANT ALL,导致后续新增的动态权限功能对已有用户不可用
动态权限和传统权限混用要注意什么
动态权限本身不替代传统权限,而是补充。例如:BACKUP_ADMIN 允许执行 BACKUP STAGE,但备份目标表仍需该用户有对应库表的 SELECT 权限;REPLICATION_APPLIER 允许启动复制通道,但读取 binlog 还需要 REPLICATION SLAVE(静态权限)。
典型组合场景:
- 逻辑备份用户:需
BACKUP_ADMIN+SELECTon target DBs +LOCK TABLES - 克隆用户:需
CLONE_ADMIN+CREATE USER(若克隆含用户)+CONNECTION_ADMIN(若远程克隆) - 审计配置用户:需
AUDIT_ADMIN+SUPER或PERSIST_RO_VARIABLES_ADMIN(用于持久化 audit_log 配置)
动态权限的注册状态依赖插件加载(如 audit_log 插件未启用,则 AUDIT_ADMIN 无意义),所以检查前先确认对应组件是否 active。










