必须显式授予system_variables_admin权限且严格匹配'user'@'host',仅on .有效,误用库表级语法会报error 1064;须依据user()结果精确授权,授完即生效,验证需用show grants for 'user'@'host'。

必须显式授予 SYSTEM_VARIABLES_ADMIN 权限,且严格匹配连接时的 'user'@'host',否则 SET PERSIST 或 SET GLOBAL 会报 ERROR 1227。
权限只能 ON *.* 授予,不能限定库或表
动态权限不支持对象粒度控制:GRANT SYSTEM_VARIABLES_ADMIN ON mydb.* TO 'u'@'%' 会直接报 ERROR 1064。MySQL 8.0 要求必须写成:
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'admin'@'192.168.1.5';
常见错误包括:
- 误用通配符库名(如
ON `tmp_%`.*)——语法非法 - 省略
@'host'导致实际匹配失败('admin'≠'admin'@'localhost') - 用
%替代具体 IP 或域名,违反最小权限原则
必须用 USER() 的结果授予权限,不是 CURRENT_USER()
CURRENT_USER() 返回认证用户,USER() 才是连接时声明的身份,而权限检查只认后者。执行:
SELECT USER(), CURRENT_USER();
取第一列结果(如 'devops'@'10.20.30.40'),然后用它授予权限:
- 如果返回
'devops'@'10.20.30.40',就授给这个精确值 - 别写成
'devops'@'%'—— 即使网络层做了 NAT,MySQL 仍按原始 IP 匹配 - 授完无需
FLUSH PRIVILEGES,权限立即生效
验证和常见绕过点
授完权限后,立刻验证是否真生效:
- 执行
SHOW GRANTS FOR 'devops'@'10.20.30.40';,确认输出含SYSTEM_VARIABLES_ADMIN - 别只信
SHOW GRANTS FOR CURRENT_USER(),它可能漏掉刚授的权限 - 注意大小写:权限名必须全大写、下划线完整,
system_variables_admin或System_Variables_Admin都无效 - 检查是否残留
CONNECTION_ADMIN或SESSION_VARIABLES_ADMIN—— 它们也能执行变量修改,容易掩盖授权问题
真正难处理的是权限已授但行为异常:比如 SET PERSIST 成功了,但重启后失效——那问题不在授权,而在 mysqld-auto.cnf 写入失败或配置文件里有同名变量覆盖。











