授予system_variables_admin权限是执行set persist的唯一正确方式,需显式授权且不继承,权限范围仅限.,主机须精确匹配,授完即生效;同时须确保变量可动态修改、mysqld-auto.cnf目录可写。

授予 SYSTEM_VARIABLES_ADMIN 权限是唯一正确方式
想让 MySQL 用户执行 SET PERSIST,必须显式授予 SYSTEM_VARIABLES_ADMIN 权限——它和 SET_USER_ID、SUPER、ALL PRIVILEGES 完全无关,也不会继承。哪怕你用 root@localhost 登录,只要没授这个权限,照样报错 ERROR 1227 (42501)。
正确授权命令如下:
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'admin_user'@'192.168.1.%';
- 主机部分不能写
'%'(除非你真要允许任意 IP),生产环境建议限定具体网段或容器 IP - 权限范围只能是
*.*,不支持数据库或表级限制 - 授完权后无需
FLUSH PRIVILEGES,GRANT语句本身已实时生效 - 验证是否成功:运行
SHOW GRANTS FOR 'admin_user'@'192.168.1.%';,确认输出中包含该权限项
为什么 SET PERSIST 还是失败?检查这三处硬性依赖
SET PERSIST 成功需要同时满足权限、变量可动态修改、文件系统可写三个条件,缺一不可。常见卡点如下:
- 权限匹配必须严格对应连接时的
user@host组合:应用连的是app@10.20.30.5,但你授的是app@'%',权限不生效 - 目标变量必须满足
IS_DYNAMIC = 'YES'且VARIABLE_SCOPE = 'GLOBAL',查法:SELECT VARIABLE_NAME, VARIABLE_SCOPE, IS_DYNAMIC FROM performance_schema.variables_info WHERE VARIABLE_NAME = 'max_connections'; -
mysqld-auto.cnf所在目录(即@@datadir)必须可写;Docker 容器里挂载为只读、磁盘满、SELinux 限制都可能触发ERROR 3615 (HY000)
SET PERSIST 和 SET PERSIST_ONLY 的权限差异
两者都写 mysqld-auto.cnf,但权限要求不同:
-
SET PERSIST max_connections = 500;→ 只需SYSTEM_VARIABLES_ADMIN -
SET PERSIST_ONLY log_bin = OFF;→ 需要SYSTEM_VARIABLES_ADMIN+PERSIST_RO_VARIABLES_ADMIN(普通 DBA 通常没有后者) - 对只读变量(如
datadir、port)直接用SET PERSIST会报ERROR 1238 (HY000),此时只能改配置文件重启
误操作后如何安全清理?别碰 mysqld-auto.cnf 文件
mysqld-auto.cnf 是 JSON 格式、由 MySQL 自动管理的文件,手动编辑极易损坏结构,导致启动失败。出问题时优先用 SQL 操作:
- 清空某变量持久化记录:
RESET PERSIST max_connections;(仅删文件和performance_schema.persisted_variables中的条目,不影响当前运行值) - 临时跳过加载:
mysqld --persisted_globals_load=OFF启动 - 彻底重置(慎用):
rm $(mysql -Nse"SELECT @@datadir;")/mysqld-auto.cnf,但必须确保 MySQL 已停机
真正容易被忽略的是:即使 SET PERSIST 返回成功,如果 mysqld-auto.cnf 所在目录权限不对、JSON 元信息时间戳异常、或与其他持久化项冲突,MySQL 下次启动时仍可能静默忽略该设置——得去错误日志里翻 Failed to load persisted variables 这类提示。











