在 MySQL 中,SET GLOBAL 和 SET PERSIST 都用于动态修改全局系统变量(global system variables),但它们在持久性 和作用范围上有显著区别。
一、基本概念
1. 系统变量分类
MySQL 的系统变量分为两类:
- 会话变量(Session Variables):仅对当前连接有效。
- 全局变量(Global Variables):对所有新建立的会话生效(部分变量也会影响运行中的会话)。
通过 SET 语句可以修改这些变量。
二、SET GLOBAL 详解
语法:
sql
SET GLOBAL variable_name = value;
-- 或简写为
SET @@global.variable_name = value;
特点:
- 作用范围 :立即生效,影响所有新建立的会话(部分变量也会立即影响已有会话)。
- 持久性 :不持久 。MySQL 重启后,该设置会丢失,恢复为配置文件(如
my.cnf)中定义的值或默认值。 - 权限要求 :需要
SYSTEM_VARIABLES_ADMIN(MySQL 8.0+)或SUPER权限(旧版本)。 - 适用场景:临时调整参数进行测试、调试或紧急修复。
示例:
sql
SET GLOBAL max_connections = 500;
此设置在 MySQL 重启后失效。
三、SET PERSIST 详解(MySQL 8.0 引入)
语法:
sql
SET PERSIST variable_name = value;
特点:
-
作用范围 :与
SET GLOBAL相同------立即生效,影响所有新会话。 -
持久性 :持久化 。MySQL 会将该设置写入数据目录下的
mysqld-auto.cnf文件(JSON 格式),在下次启动时自动加载。 -
覆盖顺序 :启动时变量值的优先级为:
默认值 < my.cnf 配置 < mysqld-auto.cnf (PERSIST 设置) < 命令行参数因此,
PERSIST的值会覆盖my.cnf中的同名设置(除非使用命令行参数覆盖)。 -
权限要求 :同样需要
SYSTEM_VARIABLES_ADMIN权限。 -
适用场景:希望动态修改配置并使其在重启后仍然生效,而无需手动编辑配置文件。
示例:
sql
SET PERSIST max_connections = 500;
重启后依然有效。
四、SET PERSIST_ONLY 详解
除了 PERSIST,MySQL 8.0 还提供了:
sql
SET PERSIST_ONLY variable_name = value;
MySQL 8.0 引入 SET PERSIST_ONLY 是为了解决一个关键的运维痛点:如何安全、统一地管理那些只能在服务启动时生效(即"只读"或"静态")的系统变量,而无需直接编辑配置文件。
特点:
- 不立即生效 ,只写入
mysqld-auto.cnf。 - 适用于那些只能在启动时设置 的只读变量(如
innodb_log_file_size),虽然不能动态修改,但可通过PERSIST_ONLY预设下次启动的值(需配合重启生效)。 - 实际上,对于可动态修改的变量,
PERSIST_ONLY不会改变当前运行时的值。
核心思想:
"所有配置变更都应通过 SQL 接口进行,由 MySQL 自身管理持久化存储。"
因此:
- 对于动态变量 → 用
SET PERSIST(立即生效 + 持久化) - 对于静态变量 → 用
SET PERSIST_ONLY(仅持久化,下次启动生效)
这样就实现了:
✅ 统一的配置管理入口
✅ 权限控制(仅需 SYSTEM_VARIABLES_ADMIN)
✅ 审计友好
✅ 与配置文件解耦
工作机制:
sql
SET PERSIST_ONLY innodb_log_file_size = 268435456; -- 256MB
执行后:
- MySQL 不会尝试修改当前运行值(因为该变量是只读的);
- 将
(innodb_log_file_size, 268435456)写入数据目录下的mysqld-auto.cnf(JSON 格式); - 下次 MySQL 启动时,会读取
mysqld-auto.cnf中的值,并作为启动参数应用; - 若该值与现有 InnoDB 日志文件大小冲突(如增大
innodb_log_file_size),MySQL 会在启动时报错,需手动清理旧日志------这与通过my.cnf设置的行为一致。
⚠️ 注意:PERSIST_ONLY 不绕过参数本身的限制,它只是提供了一种更安全的"预约设置"机制。
五、mysqld-auto.cnf 文件说明
-
路径:位于 MySQL 数据目录(如
/var/lib/mysql/mysqld-auto.cnf)。 -
格式:JSON,包含所有通过
PERSIST或PERSIST_ONLY设置的变量。 -
可读性:可读,但不建议手动编辑,应通过 SQL 命令管理。
-
重置方法:
sqlRESET PERSIST; -- 清除所有 PERSIST 设置 RESET PERSIST variable_name; -- 清除某个变量的 PERSIST 设置
六、对比总结表
| 特性 | SET GLOBAL |
SET PERSIST |
SET PERSIST_ONLY |
|---|---|---|---|
| 是否立即生效 | ✅ 是 | ✅ 是 | ❌ 否 |
| 是否持久化(重启后保留) | ❌ 否 | ✅ 是 | ✅ 是 |
写入 mysqld-auto.cnf |
❌ 否 | ✅ 是 | ✅ 是 |
| 影响当前会话 | 视变量而定 | 视变量而定 | ❌ 否 |
| 适用变量类型 | 可动态修改的全局变量 | 可动态修改的全局变量 | 所有全局变量(包括只读) |
| 权限要求 | SYSTEM_VARIABLES_ADMIN / SUPER |
同左 | 同左 |
七、使用建议
- 开发/测试环境 :常用
SET GLOBAL快速调整。 - 生产环境 :若需长期生效,推荐使用
SET PERSIST,避免因忘记更新配置文件导致重启后配置丢失。 - 审计与合规 :注意
mysqld-auto.cnf也是配置的一部分,应纳入版本控制或配置管理。 - 不要混用 :避免同时在
my.cnf和PERSIST中设置同一变量,容易造成混淆。
八、查看当前设置来源
MySQL 8.0 提供了 performance_schema.variables_info 表,可查看变量的设置来源:
sql
\SELECT
VARIABLE_NAME,
VARIABLE_SOURCE,
SET_TIME,
SET_USER
FROM performance_schema.variables_info
WHERE VARIABLE_NAME = 'max_connections';
VARIABLE_SOURCE的输出可能包括:
COMPILED(编译默认值)GLOBAL(来自SET GLOBAL)PERSISTED(来自SET PERSIST)DYNAMIC、EXPLICIT、COMMAND_LINE等
总结
SET GLOBAL:临时生效,重启失效。SET PERSIST:临时 + 永久生效(写入mysqld-auto.cnf)。SET PERSIST_ONLY:仅永久生效,不改变当前运行值。
合理使用 PERSIST 可以在不接触操作系统文件的前提下,安全地持久化配置变更,是 MySQL 8.0+ 推荐的运维实践。
如有具体变量是否支持动态修改、是否可持久化等疑问,可查询官方文档或使用:
sql
SHOW VARIABLES LIKE 'variable_name';
SELECT * FROM performance_schema.variables_info WHERE VARIABLE_NAME = '...';