SET PERSIST将配置写入数据目录(SELECT @@datadir确认)下的mysqld-auto.cnf文件,该文件为JSON格式、自动管理、不可手动编辑;加载优先级最高,启动时最后加载并覆盖my.cnf等传统配置。

SET PERSIST 不是“保存到 my.cnf”,而是写入独立的 mysqld-auto.cnf 文件,且重启后优先级高于传统配置文件 —— 这一点不搞清,后续排查配置失效、值被覆盖等问题会反复踩坑。
SET PERSIST 会把配置写到哪?路径和格式必须知道
它不会碰你手写的 /etc/my.cnf 或 ~/.my.cnf,而是固定写入 MySQL 数据目录(datadir)下的 mysqld-auto.cnf。你可以用这条命令确认位置:
SELECT @@datadir;
然后进对应目录检查:
ls -l $(mysql -Nse "SELECT @@datadir;")/mysqld-auto.cnf
该文件是 JSON 格式,含时间戳、操作用户等元信息,**手动编辑风险极高**:JSON 格式错一个逗号,MySQL 启动就失败。常见错误现象包括启动卡住、报错 Failed to load persisted variables 或直接退出。
- 不要用 vim 直接改它,哪怕只是想删掉某一项
- 不要用
echo或重定向覆盖它 —— 会破坏 JSON 结构 - 如果已损坏,优先用
RESET PERSIST variable_name或临时加--persisted_globals_load=OFF启动
SET PERSIST 和 SET PERSIST_ONLY 的关键区别
两者都写 mysqld-auto.cnf,但对内存中当前值的影响完全不同:
-
SET PERSIST max_connections = 500:立即生效(内存值变 500)+ 持久化(写入文件) -
SET PERSIST_ONLY max_connections = 500:只写文件,内存值不变 —— 适合“先预设、后择机生效”的场景,比如灰度切换前锁定配置
权限要求也不同:SET PERSIST_ONLY 需要额外的 PERSIST_RO_VARIABLES_ADMIN 权限,而普通 DBA 通常只有 SYSTEM_VARIABLES_ADMIN。执行时报错 ERROR 1227 (42501) 基本就是权限不够。
RESET PERSIST 不是“回滚”,而是“解除持久化绑定”
执行 RESET PERSIST max_connections 后:
-
mysqld-auto.cnf中该变量字段被移除 -
performance_schema.persisted_variables表里对应行消失 - 但
max_connections当前值仍是 500,完全不受影响 - 下次重启时,该变量退回到标准加载链:读
/etc/my.cnf→ 无则用编译默认值(如max_connections = 151)
常见误解是以为它能“恢复上次 SET GLOBAL 的值”,其实那个值早随重启丢了。真正容易被忽略的是:即使你 SET PERSIST 的值和当前值一模一样,它依然会落盘写入 mysqld-auto.cnf —— 所以别指望靠“设成一样”来规避持久化。
为什么改了却没生效?优先级和加载顺序是根因
MySQL 启动时配置加载顺序是:系统级 /etc/my.cnf → 用户级 ~/.my.cnf → mysqld-auto.cnf(最后加载,最高优先级)。但注意两个例外:
- 如果
mysqld-auto.cnf里某个变量被RESET PERSIST清掉了,它就彻底退出加载链,不再参与覆盖 - 如果在
my.cnf里显式写了max_connections = 1000,而mysqld-auto.cnf里是500,最终生效的仍是500(因为后者后加载) - 但如果
mysqld-auto.cnf被删或加载被禁(persisted_globals_load = OFF),那my.cnf的值才真正起作用
所以查配置不生效,第一反应不该是“是不是没写对”,而是跑一遍:SELECT * FROM performance_schema.persisted_variables; + SELECT @@max_connections; + SHOW VARIABLES LIKE 'max_connections';,三者对不上,基本就是加载顺序或持久化状态出了问题。











