必须同时设置read_only=on和super_read_only=on(mysql 5.7.8+),并配合专用低权限账号与磁盘水位监控,缺一不可;仅read_only无法阻止super用户、sql线程及触发器写入。

read_only=ON 但从库还能写,先查 super_read_only
MySQL 5.7.8+ 的从库只读必须双开:read_only=ON + super_read_only=ON。只设前者,SQL 线程、触发器、事件仍可写入——这不是 bug,是设计如此。
-
SELECT @@read_only, @@super_read_only;必须返回1, 1,缺一不可 -
super_read_only依赖read_only:后者为OFF时,前者设不上,会报错Variable 'super_read_only' is a read only variable - 动态设置需
SUPER权限,且重启即丢;务必写进配置并重启mysqld
配置文件改了却没生效?确认加载路径和段落作用域
MySQL 启动只认一个最终生效的配置文件,不是你改了哪个它就用哪个。
- 运行
mysqld --verbose --help | grep "Default options",看第一行列出的路径才是实际加载顺序(如/etc/mysql/my.cnf优先于/etc/my.cnf) -
read_only和super_read_only只在[mysqld]段落下有效;写在[client]或[mysql]里完全被忽略 - Docker 场景要特别注意:
--defaults-file参数会跳过默认路径;挂载配置时确认容器内路径与mysqld实际读取路径一致
SHOW VARIABLES 显示 ON,但 INSERT 还是成功?检查连接用户权限
super_read_only=ON 对 SUPER 用户无效——这是 MySQL 的明确行为,不是配置失败。
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
- 用
SELECT USER(), CURRENT_USER();确认当前连接身份,尤其是应用是否用了root或其他高权限账号 - 只读从库应使用专用账号:
CREATE USER 'ro_user'@'%' IDENTIFIED BY 'xxx'; GRANT SELECT ON *.* TO 'ro_user'@'%'; - 云 RDS(如阿里云、腾讯云)可能屏蔽
super_read_only,即使配置了也无效果;需查控制台文档或直接联系支持确认是否开放该参数
磁盘满导致自动置为只读,这个坑最隐蔽
当数据目录所在磁盘使用率 ≥ 95%,MySQL 会自动将 read_only 设为 ON 并拒绝写入,错误提示常是:The MySQL server is running with the --read-only option so it cannot execute this statement。
- 别急着改配置,先执行
df -h查磁盘空间,重点看/var/lib/mysql所在分区 - 临时释放空间可用:
DELETE FROM large_table WHERE ...; OPTIMIZE TABLE large_table;,但要注意OPTIMIZE会锁表 - 长期方案是扩容磁盘或清理归档日志:
PURGE BINARY LOGS BEFORE '2026-04-01 00:00:00';
真正让从库“物理级只读”的,从来不是单个变量,而是 read_only + super_read_only + 专用低权限账号 + 磁盘水位监控 四者闭环。少任何一环,都可能在某次主从切换、磁盘告警或权限变更后突然失效。










