SET PERSIST是MySQL 8.0+唯一能真正实现全局变量“改完重启不丢”的方式,它将配置写入数据目录下的mysqld-auto.cnf(JSON格式),而非my.cnf;仅支持VARIABLE_SCOPE='GLOBAL'且IS_DYNAMIC='YES'的变量(如max_connections、wait_timeout),datadir等只读变量不支持;需SYSTEM_VARIABLES_ADMIN权限,且数据目录必须可写。
SET PERSIST 是 MySQL 8.0+ 唯一能真正让全局变量“改完重启不丢”的方式,但它不是写进 my.cnf,而是写进 mysqld-auto.cnf —— 这个细节搞错,后续所有配置都会失效。
不是所有全局变量都支持持久化。直接执行会报错 ERROR 1238 (HY000): Variable 'xxx' is a read only variable。
VARIABLE_SCOPE = 'GLOBAL' 且 IS_DYNAMIC = 'YES'
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 —— 这些只能改 my.cnf 后重启它不在 /etc/my.cnf,也不在你挂载的配置目录里,而是固定落在 MySQL 数据目录下:
SELECT @@datadir;,然后进该目录检查是否存在 mysqld-auto.cnf
"Timestamp"、"User"、"Host" 等元信息Failed to load persisted variables 或直接退出RESET PERSIST variable_name 清除条目;若全毁,临时加启动参数 --persisted_globals_load=OFF 绕过加载两者都写同一个 mysqld-auto.cnf,但对内存值的影响完全不同:
SET PERSIST max_connections = 500; → 内存立刻变 500,且重启后仍是 500SET PERSIST_ONLY log_bin = OFF; → mysqld-auto.cnf 写入 "log_bin": "OFF",但当前内存值不变,下次启动才生效SET PERSIST 需 SYSTEM_VARIABLES_ADMIN;SET PERSIST_ONLY 还要额外 PERSIST_RO_VARIABLES_ADMIN,否则报错 ERROR 1227 (42501)
PERSIST_ONLY 适合预设那些无法热改的变量(如 innodb_log_file_size),避免配置漂移别只信 Query OK,得看两处:
SELECT * FROM performance_schema.persisted_variables WHERE VARIABLE_NAME = 'max_connections'; —— 有记录才算落盘成功@@datadir 目录,cat mysqld-auto.cnf 确认 JSON 结构合法(可用 jq . mysqld-auto.cnf 校验)RESET PERSIST max_connections 不是回滚,是彻底移除该变量在 mysqld-auto.cnf 和 performance_schema.persisted_variables 中的条目DEFAULT(如 SET PERSIST max_connections = DEFAULT;)也能清除持久化项,效果等同 RESET PERSIST
真正容易被忽略的是:Docker 容器里 @@datadir 对应的宿主机目录必须可写,否则 SET PERSIST 会静默失败(报错 ERROR 3615 (HY000): Cannot write to mysqld-auto.cnf),而很多人只检查了 /etc/mysql 挂载权限。