mysql 8.0持久化需满足persisted_globals_load=on、mysqld-auto.cnf存在且可写、performance_schema.persisted_variables有记录,三者缺一不可;重启后变量值不变才确认生效。

确认 persist 相关系统变量是否启用
MySQL 8.0 默认开启持久化功能,但前提是 persisted_globals_load 必须为 ON。它控制 MySQL 启动时是否加载 mysqld-auto.cnf 中的配置。如果被设为 OFF,哪怕你执行过 SET PERSIST,重启后也完全无效。
登录 MySQL 后直接查:
SELECT VARIABLE_NAME, VARIABLE_VALUE FROM performance_schema.variables_info WHERE VARIABLE_NAME = 'persisted_globals_load';
若返回 OFF,需在 my.cnf 的 [mysqld] 段手动添加:
[mysqld] persisted_globals_load = ON
然后重启 mysqld —— 注意:这个变量本身不支持 SET GLOBAL 或 SET PERSIST 动态修改,只能靠配置文件。
检查 mysqld-auto.cnf 是否存在且可写
SET PERSIST 成功不代表配置已落盘。它会尝试把值写入数据目录下的 mysqld-auto.cnf(JSON 格式),但该操作失败时 MySQL 往往静默跳过,只在错误日志里记一条 ERROR 3615 (HY000): Cannot write to mysqld-auto.cnf。
- 先确认数据目录位置:
SELECT @@datadir; - 进该目录看是否存在
mysqld-auto.cnf:ls -l /var/lib/mysql/mysqld-auto.cnf(路径以实际@@datadir为准) - 检查文件属主和权限:MySQL 进程必须对该目录有写权限。Docker 容器中常见问题是挂载为只读,或宿主机目录属主不是 MySQL 用户(如 UID 999)
验证 persisted_variables 表是否有记录
SHOW VARIABLES 只显示当前内存值,无法区分是来自 my.cnf、SET GLOBAL 还是 SET PERSIST。真正反映“已持久化”的唯一权威来源是 performance_schema.persisted_variables 表。
执行:
SELECT * FROM performance_schema.persisted_variables;
若为空,说明没成功持久化;若有记录,再比对 VARIABLE_VALUE 是否与你期望一致。注意:该表只存通过 SET PERSIST 或 SET PERSIST_ONLY 写入的变量,不包含 my.cnf 原始配置。
对比重启前后变量值是否一致
这是最终验真手段。很多用户卡在“以为生效了”,其实只是 SET GLOBAL 临时改了内存值。
- 执行
SET PERSIST max_connections = 300; - 立刻查:
SHOW VARIABLES LIKE 'max_connections';→ 应为 300 - 重启 MySQL:
sudo systemctl restart mysql(或容器中docker restart mysql8) - 再次登录,再查:
SHOW VARIABLES LIKE 'max_connections';→ 若仍为 300,说明持久化链路完整;若退回原值(如 151),就说明上面三步中至少有一处断了
最容易被忽略的是:即使 mysqld-auto.cnf 存在且有内容,只要启动命令里用了 --defaults-file 显式指定另一个配置文件,且该文件里又写了同名变量,就会覆盖掉持久化值——这种冲突不会报错,只会静默生效前者。











