SET PERSIST仅对同时满足IS_DYNAMIC='YES'且VARIABLE_SCOPE='GLOBAL'的变量生效,如max_connections、wait_timeout等;不支持datadir、port等只读变量,硬写报错ERROR 1238;需SYSTEM_VARIABLES_ADMIN权限且mysqld-auto.cnf可写。

SET PERSIST 能永久保存动态调优参数,但只对满足条件的变量生效——不是所有 SET GLOBAL 可改的变量都能持久化,硬写会直接报错。
哪些变量能用 SET PERSIST?先查再试
MySQL 不允许你凭经验瞎猜。执行前必须确认变量同时满足:IS_DYNAMIC = 'YES' 且 VARIABLE_SCOPE = 'GLOBAL'。
- 查法:运行
SELECT VARIABLE_NAME, VARIABLE_SCOPE, IS_DYNAMIC FROM performance_schema.variables_info WHERE VARIABLE_NAME = 'max_connections'; - 常见支持的调优参数:
max_connections、wait_timeout、innodb_buffer_pool_size(8.0.22+)、innodb_stats_persistent、log_bin(需搭配SET PERSIST_ONLY) - 典型不支持的:
datadir、port、socket、server_id——这些仍得改my.cnf+ 重启 - 报错
ERROR 1238 (HY000): Variable 'xxx' is a read only variable就说明不满足条件,别硬扛
SET PERSIST 和 SET PERSIST_ONLY 的行为差异
关键区别就一条:是否立刻修改内存值。
-
SET PERSIST max_connections = 500;→ 内存立即变成 500,同时写入mysqld-auto.cnf,重启后仍是 500 -
SET PERSIST_ONLY log_bin = OFF;→ 当前 binlog 继续开着,只把OFF写进文件,下次启动才关闭 - 两者都写同一个文件:
mysqld-auto.cnf(位于SELECT @@datadir;返回的路径下),JSON 格式,MySQL 自动管理 - 权限不同:
SET PERSIST需SYSTEM_VARIABLES_ADMIN;SET PERSIST_ONLY还要额外PERSIST_RO_VARIABLES_ADMIN
执行后为什么没生效?常见失效原因
不是语法错,而是环境或加载链路断了。
- 权限不足 → 报错
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,常见于容器挂载为只读、SELinux 启用、或datadir属主不是mysql用户 - 被覆盖 →
mysqld-auto.cnf加载优先级最高,但如果它根本没被加载(比如persisted_globals_load = OFF),或者 MySQL 启动时因 JSON 格式错误静默跳过,配置就白写了;可用SHOW VARIABLES LIKE 'persisted_globals_load';确认是否为ON - 变量需重启才生效 → 如
innodb_buffer_pool_size,SET PERSIST只保证下次启动加载,当前会话仍用旧值,别误判为失败
验证是否真正落盘?别只信 “Query OK”
命令返回成功不代表已写入磁盘或会被加载。
- 查表确认:
SELECT * FROM performance_schema.persisted_variables WHERE VARIABLE_NAME = 'max_connections';—— 有记录才算落盘 - 查文件确认:
ls -l $(mysql -Nse "SELECT @@datadir;")/mysqld-auto.cnf,然后cat看内容是否为合法 JSON(不要手动编辑!) - 注意:
SET PERSIST即使设成和当前值一样的数,也会写入文件;设为DEFAULT(如SET PERSIST max_connections = DEFAULT;)可清除该变量的持久化条目 - 最易被忽略的是:
mysqld-auto.cnf是 JSON,错一个逗号、少一个引号,MySQL 启动就会失败,且错误日志可能只提示“Failed to load persisted variables”,排查成本高


















