开发人员不应获得system_variables_admin权限,因其用于全局变量设置,易引发服务抖动;临时库权限应通过角色+对象级静态权限(如create、select等)配合库名前缀通配符(如tmp_%.*)实现安全隔离。

开发人员不该直接获得 SYSTEM_VARIABLES_ADMIN,临时数据库权限也不靠它解决——真正该用的是角色 + 对象级静态权限 + 动态权限按需补充。
为什么不能用 SYSTEM_VARIABLES_ADMIN 授开发人员临时库权限
这个权限根本不是干这事的。它允许执行 SET GLOBAL、SET PERSIST,影响整个实例行为,比如改 max_connections 或 read_only,一不小心就导致服务抖动甚至主库误写。开发连自己应用库的 SELECT 都要受限,怎么可能需要控制全局变量?
常见错误现象:
- 脚本里写了
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'dev'@'%',以为“加个权限就能临时建库”,结果用户真去执行SET GLOBAL sort_buffer_size = 1073741824,内存爆满 - 误以为授予了这个权限,开发就能
CREATE DATABASE—— 实际上CREATE DATABASE需要的是CREATE权限(静态),和动态权限无关
开发需要的“临时库权限”到底指什么
真实场景中,“临时”通常指:新项目上线前试跑、AB 测试库、CI/CD 自动建表、本地调试用的影子库。这些都不需要持久化,但需要可快速创建、读写、清理。
对应权限组合应为:
-
CREATE、DROP、ALTERon*.*或指定库模式(如dev_%)——用于建库建表 -
SELECT、INSERT、UPDATE、DELETEon those databases ——用于数据操作 - 可选:
EVENT、TRIGGER、CREATE ROUTINE——若涉及定时任务或存储过程
注意:CREATE 权限本身是静态权限,MySQL 8.0 中仍由 GRANT 直接授予,不走动态权限体系。
如何安全实现“临时库”的权限隔离
核心思路:用命名约定 + 角色 + 通配符授权,避免给 *.* 全局权限。
实操建议:
- 约定临时库名前缀,例如全部用
tmp_或devtest_开头 - 创建专用角色:
CREATE ROLE 'temp_db_dev'; - 授予权限时用反引号+通配符:
GRANT CREATE, DROP, ALTER, SELECT, INSERT, UPDATE, DELETE ON `tmp_%`.* TO 'temp_db_dev'; - 把角色赋予开发用户:
GRANT 'temp_db_dev' TO 'dev1'@'%'; - 激活角色(重要!):
SET DEFAULT ROLE ALL TO 'dev1'@'%';,否则权限不生效
这样开发能自由建 tmp_order_v2、删 tmp_cache_test,但无法碰 prod_user 或 sys 库——通配符只匹配前缀,不越界。
哪些动态权限可能真用得上(但极少)
绝大多数开发场景完全不需要动态权限。只有极少数延伸需求才涉及:
- 如果开发要执行逻辑备份(
mysqldump --single-transaction),需BACKUP_ADMIN+ 对目标库的SELECT权限 - 如果 CI 脚本要克隆一个测试实例(用
CLONE INSTANCE),需CLONE_ADMIN+CONNECTION_ADMIN(远程克隆时) - 如果调试需要绕过查询重写插件(如 Rewriter),才用到
SKIP_QUERY_REWRITE
这些不是“临时库权限”的组成部分,而是独立功能点;授之前必须确认对应功能已启用(如 clone 插件)、且有明确使用日志审计支撑。
最易被忽略的一点:角色默认不激活,GRANT role TO user 后必须显式执行 SET DEFAULT ROLE,否则开发连 SHOW DATABASES 都看不到刚建的 tmp_* 库——这不是权限没给,是角色没亮灯。











