SET PERSIST可让支持的全局变量立即生效且重启不丢,但必须满足三条件:变量IS_DYNAMIC='YES'且VARIABLE_SCOPE='GLOBAL'、用户具备SYSTEM_VARIABLES_ADMIN权限、数据目录对mysqld-auto.cnf可写;查performance_schema.variables_info表确认前两条件,典型可用变量包括max_connections、wait_timeout、innodb_buffer_pool_size(8.0.22+),不可用如datadir、port;SET PERSIST改内存并落盘,SET PERSIST_ONLY仅落盘;常见失效原因为权限不足、目录不可写或persisted_globals_load=OFF。

SET PERSIST 能让支持的全局变量既立即生效又重启不丢,但必须满足三个硬条件:变量本身可动态修改、你有 SYSTEM_VARIABLES_ADMIN 权限、MySQL 数据目录对 mysqld-auto.cnf 可写。缺一个,命令就失败,且错误提示不会直接告诉你缺哪块。
怎么确认某个变量能不能用 SET PERSIST?
不能靠经验猜,也不能硬试——报错 ERROR 1238 (HY000): Variable 'xxx' is a read only variable 就晚了。
- 查
performance_schema.variables_info表,确认两个字段同时为真:IS_DYNAMIC = 'YES'且VARIABLE_SCOPE = 'GLOBAL' - 常用可持久化变量包括:
max_connections、wait_timeout、innodb_buffer_pool_size(8.0.22+)、sql_mode - 典型不可用的有:
datadir、port、socket、server_id——这些改了也白改,必须动my.cnf+ 重启
SET PERSIST 和 SET PERSIST_ONLY 到底差在哪?
核心就一条:是否立刻改内存值。别被名字绕晕。
-
SET PERSIST max_connections = 5000;→ 内存立刻变成 5000,同时写进mysqld-auto.cnf,下次启动还是 5000 -
SET PERSIST_ONLY log_bin = OFF;→ 内存值不变(比如 binlog 还开着),只落盘;等下次启动才关闭 binlog - 权限上:
SET PERSIST_ONLY需要额外的PERSIST_RO_VARIABLES_ADMIN,普通 DBA 通常没有,执行时报ERROR 1227 (42501)基本就是这个原因
为什么改完没生效?常见卡点在哪?
不是语法错了,而是环境或加载逻辑被忽略了。
- 权限不够:
ERROR 1227 (42000): Access denied; you need SYSTEM_VARIABLES_ADMIN privilege→ 普通 root 默认没这权限,得显式授权:GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'admin'@'%'; - 目录不可写:
ERROR 3615 (HY000): Cannot write to mysqld-auto.cnf→ 容器里挂载datadir为只读、SELinux 启用、或属主不对,都会导致失败 - 文件没加载:
SHOW VARIABLES LIKE 'persisted_globals_load';如果返回OFF,那mysqld-auto.cnf根本不会被读取,所有持久化都无效 - 覆盖关系被误判:虽然
mysqld-auto.cnf优先级最高,但它只在启动最后加载;如果之前某处(比如命令行参数)已设同名变量,它仍会被覆盖
误操作后怎么安全恢复?
RESET PERSIST 不是万能回滚,它只移除持久化绑定,不改当前内存值,也不修复损坏的 JSON 文件。
- 单个变量还原:
RESET PERSIST max_connections;→ 从mysqld-auto.cnf和performance_schema.persisted_variables中清除该条目 - 文件已损坏(比如手动编辑出错导致启动失败):
mysqld --persisted_globals_load=OFF临时跳过加载,再用RESET PERSIST或删掉整个mysqld-auto.cnf - 最易被忽略的一点:
mysqld-auto.cnf是 JSON 格式,结构极其脆弱——少个逗号、多空格、时间戳格式错,MySQL 启动就会卡住或直接退出,且错误日志里未必明确指出是它的问题


















