SET PERSIST仅支持动态全局变量(IS_DYNAMIC='YES'且VARIABLE_SCOPE='GLOBAL'),如max_connections、innodb_buffer_pool_size;server_id、log_bin、binlog_format、relay_log、read_only等主从核心变量为只读,必须静态配置于my.cnf并重启生效。

主从复制本身不依赖 MySQL 的 SET PERSIST 功能,但你在配置主库或从库时,若想让关键系统变量(如 server_id、log_bin、binlog_format)在重启后依然生效,必须区分清楚:哪些变量能用 SET PERSIST,哪些根本不能——否则会报错或被忽略。
哪些变量支持持久化?哪些根本不支持?
MySQL 8.0+ 的 SET PERSIST 只对「动态全局变量」且标记为 PERSISTABLE=YES 的才有效。像 server_id、log_bin、read_only 这类控制复制行为的核心变量,**全部是只读变量(READ_ONLY=ON)**,无法通过 SET PERSIST 修改,强行执行会直接报错:
ERROR 1238 (HY000): Variable 'server_id' is a read only variable
这类变量只能写进配置文件(如 my.cnf 或容器挂载的 master.cnf),靠 MySQL 启动时加载生效。
-
max_connections、innodb_buffer_pool_size等运行时可调变量,支持SET PERSIST -
server_id、log_bin、binlog_format、relay_log、read_only必须静态配置 - 执行
SELECT * FROM performance_schema.variables_info WHERE VARIABLE_NAME IN ('server_id', 'log_bin');可查PERSISTABLE和READ_ONLY字段确认
如何让主从配置真正“永久生效”?
主从复制的稳定性取决于启动时就加载正确的配置,而不是靠运行时设置。哪怕你用 SET GLOBAL log_bin = ON 成功了,重启后照样失效——因为 log_bin 是只读变量,MySQL 启动时仍按配置文件决定是否开启 binlog。
- 主库必须在
[mysqld]段中显式启用:log_bin = mysql-bin+server_id = 1 - 从库必须配置:
server_id = 2+relay_log = relay-bin+read_only = ON - Docker 部署时,把
master.cnf和slave.cnf挂载到容器内/etc/mysql/conf.d/下,而非仅靠docker run -e传参 - 不要依赖
SET PERSIST去“修复”遗漏的静态配置——它做不到
为什么有人误以为 SET PERSIST 能配主从?
常见混淆点在于:看到 SET PERSIST read_only = ON 执行成功,就以为能替代配置文件。但实际上,read_only 在 MySQL 8.0.22+ 才支持 PERSIST(且仅限非超级用户场景下有限使用),而主从环境里它通常需在启动前就设好,否则从库可能在复制线程启动前接受写入,造成数据不一致。
-
read_only = ON若用SET PERSIST设置,仅对后续连接生效,不影响已存在的连接或复制线程 - 主库的
log_bin和从库的relay_log根本不接受任何SET类命令,连SET GLOBAL都被拒绝 -
mysqld-auto.cnf文件里写入的变量,启动时优先级低于my.cnf,但**不覆盖只读变量**——它只影响可持久化的动态变量
真正需要持久化的,是那些运行时可能被临时调整、又希望重启不失效的变量(比如调优用的 innodb_buffer_pool_size)。主从拓扑结构相关的变量,从第一天起就必须固化在配置文件里——这是唯一可靠的方式。


















