MySQL 8.0 的 SET PERSIST 解决了“改了就丢”运维痛点,要求变量同时满足 IS_DYNAMIC='YES' 且 VARIABLE_SCOPE='GLOBAL',并需 SYSTEM_VARIABLES_ADMIN 权限;SET PERSIST 立即生效并持久化,SET PERSIST_ONLY 仅持久化、重启生效。

它解决了“改了就丢”这个高频运维问题:MySQL 8.0 之前,SET GLOBAL 只改内存值,重启后立即回退到 my.cnf 或启动参数里的旧值,必须手动同步配置文件,极易出错或遗漏。
哪些变量能用 SET PERSIST?
不是所有全局变量都支持——硬试会直接报错:ERROR 1238 (HY000): Variable 'xxx' is a read only variable。
必须同时满足:
-
IS_DYNAMIC = 'YES'(支持运行时修改) -
VARIABLE_SCOPE = 'GLOBAL'(不能是 SESSION 级)
查法: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+)、sql_mode
典型不支持的:datadir、port、socket、server_id——这些仍得改 my.cnf + 重启
SET PERSIST 和 SET PERSIST_ONLY 的关键区别
核心就一点:是否立刻改内存值。
-
SET PERSIST max_connections = 500;→ 内存立刻变 500,同时写入mysqld-auto.cnf,重启后仍是 500 -
SET PERSIST_ONLY log_bin = OFF;→ 内存值不变(比如 binlog 还开着),只写进mysqld-auto.cnf,下次重启才关闭
权限也不同:SET PERSIST 需 SYSTEM_VARIABLES_ADMIN;SET PERSIST_ONLY 还要额外 PERSIST_RO_VARIABLES_ADMIN
典型用途:PERSIST_ONLY 适合改那些当前无法动态关闭的变量(如依赖 binlog 的复制设置),先落盘,等重启生效
执行失败的常见原因和检查项
报错基本不是语法问题,而是环境卡住:
-
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→ 数据目录不可写(容器挂载为ro、SELinux 启用、或mysqld进程属主无写权限) - 改完没生效?检查是否被
my.cnf里同名参数覆盖了——虽然mysqld-auto.cnf优先级最高,但前提是它被成功加载;可用SHOW VARIABLES LIKE 'persisted_globals_load';确认该开关是否为ON
文件位置由 SELECT @@datadir; 确认,内容是 JSON 格式,千万别手动编辑 mysqld-auto.cnf——解析失败会导致 MySQL 启动失败


















