必须同时确认read_only和super_read_only均为ON才真正生效;云RDS可能屏蔽super_read_only,磁盘满≥95%会静默启用read_only,导致“只读”非配置所致。

super_read_only = ON 但写入仍成功?先确认它真生效了
直接查变量值,别信配置文件或记忆:SELECT @@GLOBAL.super_read_only; 返回 1 或 ON 才算生效。返回 0 或 OFF 就说明根本没开——常见原因是云 RDS(如阿里云、腾讯云)屏蔽该参数,SET GLOBAL super_read_only = ON 看似执行成功,但实际被忽略,日志里可能有 Variable 'super_read_only' is a read-only variable 提示。
检查方式必须是运行时查询,不是翻 my.cnf;若用容器或云实例,优先查控制台文档是否明确支持该参数。
MySQL 版本和启动顺序不满足要求
super_read_only 从 MySQL 5.7.8 才引入,5.7.7 及更早版本压根不识别这个变量。即使你写了 super_read_only = ON 到配置文件,mysqld 启动会直接报错退出,或者静默跳过。
更重要的是两个参数的依赖关系:
-
read_only = ON必须在配置文件中先出现,super_read_only = ON写在它后面 - 如果顺序颠倒,MySQL 启动失败或
super_read_only不加载 - 动态设置也必须按序:
SET GLOBAL read_only = ON;→SET GLOBAL super_read_only = ON;,反过来会报ERROR 1290
账号权限绕过了 super_read_only 的限制
super_read_only = ON 确实拦住了绝大多数写操作,但它不拦某些元数据级语句,比如:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
-
FLUSH LOGS、FLUSH STATUS、RESET SLAVE -
ANALYZE TABLE(MySQL 8.0+ 对系统表也生效) -
INSTALL PLUGIN、CREATE FUNCTION(除非innodb_read_only = ON)
这些操作本身不改业务数据,但可能更新系统表、触发复制状态变更或破坏一致性。更关键的是:如果你用的是 root@'%' 这类全通配账号,而该账号还拥有 SYSTEM_VARIABLES_ADMIN 或 CONNECTION_ADMIN 权限,部分写行为仍可能绕过。
磁盘满导致 read_only 被自动开启,掩盖了 super_read_only 的真实状态
当 /var/lib/mysql 所在分区使用率 ≥95%,MySQL 会静默把 read_only 设为 ON,但 super_read_only 保持原值不变。此时你看到的“只读”其实是磁盘保护机制触发的,不是你配的 super_read_only 在起作用。
排查步骤:
- 运行
df -h,重点看 MySQL 数据目录所在挂载点 - 查
SELECT @@GLOBAL.read_only, @@GLOBAL.super_read_only;—— 如果前者是ON而后者是OFF,基本就是磁盘问题 - 清理空间后,
read_only不会自动恢复,必须手动SET GLOBAL read_only = OFF
真正兜底的只读,得同时满足:版本支持、配置顺序正确、变量双 ON、磁盘健康、账号无冗余高权限——漏掉任一环,都可能让“已设 super_read_only”变成一句空话。










