必须显式授予SYSTEM_VARIABLES_ADMIN权限且严格匹配USER()返回的'user'@'host',仅ON .有效;误用通配符、大小写错误、授给角色或遗漏FLUSH PRIVILEGES均导致失效。

必须显式授予,且严格匹配连接时的 'user'@'host',否则 SET PERSIST 或 SET GLOBAL 一定报错。
为什么 GRANT SYSTEM_VARIABLES_ADMIN 总是不生效
常见错误不是语法写错,而是身份不匹配。MySQL 校验的是你实际连接用的 USER(),不是 CURRENT_USER()。比如你用 admin@'192.168.1.5' 登录,但执行了 GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'admin'@'%',权限就无效——'%' 不匹配具体 IP。
- 先确认真实连接身份:
SELECT USER(), CURRENT_USER();,取USER()的结果(如'devops'@'10.20.30.40') - 授予权限时必须一字不差:
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'devops'@'10.20.30.40'; - 别用
'%'或'localhost'混用:Linux 下localhost走 socket,127.0.0.1走 TCP,是两个不同 host - 授完不用
FLUSH PRIVILEGES,动态权限立即生效
SET PERSIST 报 ERROR 1227 的直接原因
报这个错,99% 是因为没给对权限主体。它和传统静态权限不同:不能靠角色间接获得,不能通配库表,也不能被 WITH GRANT OPTION 传播。
-
SYSTEM_VARIABLES_ADMIN只能授给用户,不能授给角色(GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'role_name'会报错) - 必须写成
ON *.*,写成ON mydb.*或ON *.都非法,触发ERROR 1064 - 权限名大小写敏感,
system_variables_admin或System_Variables_Admin全部无效 - 验证是否生效:
SHOW GRANTS FOR 'devops'@'10.20.30.40';输出里必须出现完整大写权限名
授完还是不能 SET GLOBAL?检查这三个绕过点
即使 SHOW GRANTS 看起来正确,SET GLOBAL 仍可能成功——说明权限没真正拦住,大概率是其他高危权限在起作用。
-
SESSION_VARIABLES_ADMIN:允许SET PERSIST,效果等同于持久化改全局变量,常被忽略 -
CONNECTION_ADMIN:隐式包含所有变量修改能力,还能KILL连接、CREATE USER,权限位最高 -
SUPER:虽然 8.0.16+ 已废弃,但若还存在,会完全覆盖动态权限控制逻辑 - 查全权限链:
SHOW GRANTS FOR 'devops'@'10.20.30.40' USING 'role_name';(如果用了角色)
生产环境必须配套做的三件事
只执行 GRANT 是危险的起点,不是终点。漏掉任一环节,等于留后门。
- 禁用
GRANT OPTION:REVOKE GRANT OPTION ON *.* FROM 'devops'@'10.20.30.40';,防止权限扩散 - 开启审计日志(如
mysql_enterprise_audit_log),至少记录所有SET GLOBAL和SET PERSIST操作 - 在配置文件中限制可修改变量范围(
set-variable-perms=OFF不可用,但可通过read_only=ON+ 白名单脚本做二次校验)
真正的难点不在怎么授,而在授完之后如何确保它只在预期场景下被调用——max_connections 被调高可能撑爆内存,read_only 被关掉可能破坏主从一致性,这些都不是权限语句本身能防护的。


















