只有同时满足IS_DYNAMIC='YES'且VARIABLE_SCOPE='GLOBAL'的全局变量才支持SET PERSIST,如max_connections、wait_timeout、innodb_buffer_pool_size(8.0.22+);datadir、port等只读参数不支持,须改配置文件后重启。

哪些变量能用 SET PERSIST?先查再改
不是所有全局变量都支持 SET PERSIST。直接执行会报错 ERROR 1238 (HY000): Variable 'xxx' is a read only variable。必须确认变量同时满足两个条件:动态可改(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(MySQL 8.0.22+)、log_bin(需搭配SET PERSIST_ONLY) - 典型不支持的:
datadir、port、socket——这些必须改my.cnf+ 重启
SET PERSIST 和 SET PERSIST_ONLY 到底差在哪?
核心区别就一条:是否立刻应用到内存。
-
SET PERSIST max_connections = 5000;→ 当前立即生效 + 写入mysqld-auto.cnf→ 重启后仍是 5000 -
SET PERSIST_ONLY log_bin = OFF;→ 只写入mysqld-auto.cnf,当前值不变 → 下次启动才生效(适合不能热改的参数) - 两者都写同一个文件:
mysqld-auto.cnf,位于 MySQL 数据目录下,JSON 格式,由 MySQL 自动管理 - 千万别手动编辑
mysqld-auto.cnf,格式出错会导致启动失败
执行 SET PERSIST 前必须检查的三件事
权限、路径、冲突配置——漏一个就失败。
- 权限:需要
SYSTEM_VARIABLES_ADMIN。普通root默认没有,得显式授权:GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'admin'@'%'; - 目录可写:
mysqld-auto.cnf所在目录(即数据目录)必须可写,否则报错ERROR 3615 (HY000): Cannot write to mysqld-auto.cnf(Docker 容器里挂载为只读很常见) - 配置优先级:启动时顺序是「命令行参数 >
mysqld-auto.cnf>my.cnf」,所以mysqld-auto.cnf里的值会覆盖my.cnf中同名项;若想绕过它,可设persisted_globals_load=OFF启动
怎么验证 SET PERSIST 成功落盘了?
别只信命令没报错,得看实际写进去了没。
- 查持久化记录:
SELECT * FROM performance_schema.persisted_variables;—— 这里显示的是已写入mysqld-auto.cnf的变量,不是当前运行值 - 对比当前值:
SHOW GLOBAL VARIABLES LIKE 'max_connections';确认内存中也已更新(仅对SET PERSIST有效,SET PERSIST_ONLY不影响此项) - 重启后再次查
SHOW GLOBAL VARIABLES,才是最终检验 - 如果误操作写错了,可用
RESET PERSIST max_connections;清除该变量的持久化记录(注意:不清除当前内存值)
最常被忽略的是权限和目录写入权限——尤其在容器或受限系统中,SET PERSIST 看似一行命令,背后依赖两个隐性条件:用户有 SYSTEM_VARIABLES_ADMIN,且 MySQL 进程对数据目录有写权限。











