set persist 必须依赖 innodb 引擎,因为其持久化机制依托 mysql.persisted_variables 系统表(强制 innodb),通过 redo/undo log 保障写入原子性与崩溃恢复,并依赖行锁和 mvcc 实现并发安全;myisam 无法满足该强一致性要求。

SET PERSIST 为什么必须依赖 InnoDB 引擎
因为 SET PERSIST 修改的变量值,最终要持久化到磁盘上的 mysqld-auto.cnf 文件,而该文件的写入、校验、原子性保障全部由 InnoDB 的事务机制兜底——不是“用了 InnoDB 就能用”,而是“没 InnoDB 就根本没法安全落地”。
mysqld-auto.cnf 不是普通配置文件,它受 InnoDB 系统表保护
MySQL 8.0 把所有可持久化的全局变量映射到内部系统表 mysql.persisted_variables,这个表的引擎强制为 InnoDB。这意味着:
- 每次
SET PERSIST都是一次带 redo log 和 undo log 的事务写入,崩溃后可恢复 - 并发执行多个
SET PERSIST不会互相覆盖,靠行锁和 MVCC 保证顺序 - 如果手动编辑
mysqld-auto.cnf文件(比如删掉某行),MySQL 启动时会自动从mysql.persisted_variables表重建该文件,而不是信任文本内容
MyISAM 在这里完全不可行
假设系统表仍用 MyISAM:
- 宕机时
mysql.persisted_variables可能只写了一半,重启后mysqld-auto.cnf生成错误配置,导致实例无法启动 -
SET PERSIST max_connections=1000和SET PERSIST wait_timeout=300并发执行,可能一个写入成功、另一个静默丢失 - 没有事务回滚能力,一旦写错参数(比如把
innodb_buffer_pool_size设成 0),连连接都建立不了,更没法 rollback
你看到的“配置生效”,背后是 InnoDB 的两次落盘
执行 SET PERSIST innodb_buffer_pool_size = 2G 后,实际发生:
- 第一步:InnoDB 把新值写进
mysql.persisted_variables表,并刷入 redo log - 第二步:MySQL 主线程读取该表,生成/覆盖
mysqld-auto.cnf,并 fsync 到磁盘 - 如果第一步失败,第二步根本不会触发;如果第二步失败,下次启动时仍会从表重建文件
这种强一致性链条,只有 InnoDB 能闭环。任何试图绕过它(比如直接改 cnf 文件再 reload)都会让 PERSIST 机制失去意义——变量还是变了,但不再“持久”。











