必须先启用read_only=ON,再设super_read_only=ON,二者均需持久化至[mysqld]段并重启生效;否则super_read_only静默失效,root仍可写入。

只开 super_read_only = ON 不够,必须确保 read_only = ON 已先启用、且两者都持久化到配置文件并重启生效,否则要么启动失败,要么形同虚设。
为什么 SET GLOBAL super_read_only = ON 后 root 还能写?
常见现象:执行了 SET GLOBAL super_read_only = ON,但用 root@localhost 登录后仍能 DROP TABLE 或 INSERT。这不是命令没生效,而是你漏掉了前提——super_read_only 依赖 read_only 先为 ON。MySQL 会静默拒绝该设置,并报错:ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement(注意:这个错误是“试图关它”时才出现;而“开它失败”往往无提示,查 SHOW VARIABLES LIKE 'super_read_only' 才发现仍是 OFF)。
根本原因:super_read_only = ON 要求 read_only 必须已为 ON;若 read_only 是 OFF,MySQL 直接忽略该设置,不报错也不生效。
- 检查当前状态:
SELECT @@read_only, @@super_read_only;—— 两个都得是1 - 确认是否真被拒绝:用
root执行SET GLOBAL read_only = OFF,如果报ERROR 1290,说明super_read_only实际已生效;如果成功,则它根本没开起来 - 别信
SHOW VARIABLES单独结果:要同时查两个变量,缺一不可
配置文件里怎么写才不启动失败?
在 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf 的 [mysqld] 段下,顺序和格式必须严格:
✅ 正确写法(顺序不能颠倒,值必须是 ON,不能是 1 或 true):
[mysqld] read_only = ON super_read_only = ON
❌ 错误写法:
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
-
super_read_only = ON写在read_only = ON前面 → MySQL 启动失败,报错Unknown variable 'super_read_only'或直接退出 - 写进
[client]或[mysql]节 → MySQL 静默忽略,启动成功但参数无效 - 写成
read_only = 1→ 大部分版本兼容,但官方只保证ON/OFF行为一致,建议统一用大写 - 漏掉
[mysqld]节头 → 配置不加载
MySQL 8.0+ 推荐用 SET PERSIST,但要注意陷阱
如果你无法直接改配置文件(比如容器或云 RDS),SET PERSIST super_read_only = ON 是更安全的替代方案——它会把值写入 mysqld-auto.cnf,优先级高于 my.cnf,且重启不丢失。
但必须满足两个前提:
- MySQL 版本 ≥ 8.0.22(低于此版本不支持
PERSIST) - 执行用户必须有
PERSIST_RO_VARIABLES_ADMIN权限(root默认有,普通账号需显式授权) - 执行前必须先确保
read_only已为ON,否则SET PERSIST super_read_only = ON会静默失败
验证是否写入成功:SELECT * FROM performance_schema.persisted_variables WHERE VARIABLE_NAME IN ('read_only', 'super_read_only'); —— 两行都应存在且 VARIABLE_VALUE 为 ON。
开了 super_read_only,哪些操作仍可能“偷偷写”?
super_read_only = ON 确实拦住了 INSERT/UPDATE/DROP/CREATE FUNCTION 等绝大多数写操作,但它不拦:
-
CREATE TEMPORARY TABLE:临时表不受限制,应用若大量创建再丢弃,可能耗尽 tmpdir 空间 -
FLUSH LOGS、RESET MASTER:不改业务数据,但会破坏 relay log 位点或清空 binlog,导致主从断裂 -
ANALYZE TABLE(MySQL 8.0+):更新统计信息,写系统表,会被拒绝;但低版本可能绕过 - 磁盘满 ≥95%:MySQL 自动触发保护,静默设
read_only = ON,此时super_read_only仍为OFF,但你看到的错误一模一样 —— 先df -h /var/lib/mysql
真正兜底不是只靠一个开关,而是三件事同步做:配对启用 read_only 和 super_read_only、回收所有账号的 SUPER 权限、监控磁盘与连接来源。漏掉任何一环,只读就只是个幻觉。

















