mysql 8.0通过session_variables_admin等动态权限实现按需授权,取代super;须on .授予,不支持库表级;需usage权限、重连生效,且角色需显式授予并设为默认。

session_variables_admin 和 system_variables_admin 这类动态权限,是 MySQL 8.0 真正开始支持“按需授权”的关键突破——它让你能剥离掉过去必须捆绑授予的 SUPER 权限,只给用户改变量的权力,不给重启、刷日志、重设主从这些高危能力。
动态权限 ≠ 静态权限,不能用 GRANT ON database.table 语法
动态权限作用于整个服务器实例,只能在全局层级(ON *.*)授予或回收,且不支持数据库/表级限定。常见错误是写成:GRANT session_variables_admin ON mydb.* TO 'user'@'%'——这会报错 ERROR 1064 (42000),因为语法不合法。
- 正确写法必须是:
GRANT session_variables_admin ON *.* TO 'user'@'%' - 动态权限列表可通过
SELECT * FROM information_schema.role_table_grants WHERE privilege_type LIKE '%_admin'查看(注意不是所有都带_admin后缀) - MySQL 8.0.16+ 新增的
PERSIST支持让动态权限配置落盘,避免重启丢失:SET PERSIST session_variables_admin = ON;,但该语句只影响当前账户的默认状态,不等价于GRANT
哪些操作必须用动态权限?典型场景对照表
传统上靠 SUPER 实现的功能,现在可拆解为更小粒度的动态权限。比如:
-
SET GLOBAL sort_buffer_size = 4194304→ 需要system_variables_admin -
SET SESSION wait_timeout = 600→ 需要session_variables_admin -
FLUSH BINARY LOGS→ 需要BINLOG_ADMIN -
STOP SLAVE→ 需要REPLICATION_SLAVE_ADMIN -
KILL 12345→ 需要CONNECTION_ADMIN(替代旧版SUPER中的连接控制部分)
注意:SUPER 在 8.0.16+ 已被标记为废弃,执行 REVOKE SUPER ON *.* FROM 'u'@'%' 会触发 warning,但不会失败;回收后若功能异常,说明遗漏了对应动态权限。
授完动态权限,用户仍无法执行命令?检查三件事
动态权限生效有隐式前提,容易漏掉:
- 用户必须拥有
USAGE权限(新建用户时自动具备,但通过REVOKE ALL清空后可能丢失) - 权限变更后,已有连接不会自动继承新权限,必须重连;连接池(如 HikariCP)需配置
connection-init-sql=SET ROLE NONE或显式SET ROLE初始化 - 某些动态权限(如
ROLE_ADMIN)还依赖用户是否被显式授予角色,单纯GRANT ... ON *.*不够,还需GRANT 'role_name' TO 'user'@'%'并激活
生产环境慎用 activate_all_roles_on_login
虽然 SET PERSIST activate_all_roles_on_login = ON 能让所有用户登录即激活全部已授角色(含带动态权限的角色),但它绕过了显式角色选择逻辑,一旦某个角色误配了高危动态权限(如 SYSTEM_VARIABLES_ADMIN),所有绑定该角色的用户都会获得该能力——这与最小权限原则直接冲突。更稳妥的做法是:对每个需要动态权限的用户,单独 SET DEFAULT ROLE 指定一个精简角色,且该角色只含必要动态权限。











