能写——只要用户有 super 或 system_variables_admin 权限,read_only=on 对他们完全无效;这是 mysql 的防误操作机制,非权限控制开关。

mysql 设置 read_only 后,普通用户还能写吗?
能写——只要用户有 SUPER 或 SYSTEM_VARIABLES_ADMIN 权限,read_only=ON 对他们完全无效。这是 MySQL 的设计逻辑:read_only 是“防误操作”机制,不是权限控制开关。
常见错误现象:SET GLOBAL read_only = ON 后,应用仍能成功执行 INSERT 或 UPDATE,以为配置没生效;其实只是连接用的账号权限太高。
- 真正受限制的是普通账号(仅含
SELECT/INSERT等对象级权限) -
root默认带SUPER,所以几乎总能绕过read_only - MySQL 8.0.12+ 推荐用
SYSTEM_VARIABLES_ADMIN替代SUPER,但效果一样
如何让 read_only 真正生效?必须配权限隔离
只设 read_only=ON 不够,得配合账号权限收紧。否则主库变只读形同虚设。
使用场景:主从切换后临时锁定主库、上线前保护核心库、避免运维手抖删库。
- 先执行
SET GLOBAL read_only = ON - 再回收高权限:对业务账号执行
REVOKE SUPER ON *.* FROM 'app_user'@'%' - 确认无残留:查
SELECT user, super_priv FROM mysql.user WHERE user = 'app_user',结果应为N - 注意:修改权限后需
FLUSH PRIVILEGES,且已存在的连接不会立即失效
read_only 和 super_read_only 有什么区别?
super_read_only 是更严格的只读开关,它会强制覆盖所有账号(包括 root),除非你先关掉它才能改其他系统变量。
参数差异:
-
read_only=ON:允许SUPER用户写,允许修改大多数全局变量 -
super_read_only=ON:禁止所有用户写(包括SUPER),且自动置read_only=ON;此时连SET GLOBAL read_only = OFF都会报错ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement - 生产环境建议优先开
super_read_only,尤其在 MHA / Orchestrator 等高可用架构中
为什么 set read_only 不持久?重启就失效
因为 SET GLOBAL 只改内存值,不写配置文件。MySQL 重启后恢复默认(read_only=OFF)。
性能 / 兼容性影响:无。该变量本身无运行时开销,但依赖它做只读保护的系统,若未落盘配置,等于裸奔。
- 正确做法:在
my.cnf的[mysqld]段加super_read_only=ON(MySQL 5.7.20+)或read_only=ON - 注意路径:必须是 MySQL 启动时实际加载的配置文件,可通过
mysqld --help --verbose | grep "Default options"确认 - 改完要重启 mysqld,或用
mysqladmin shutdown+ 手动启,SIGHUP不重载此变量
最容易被忽略的是:以为开了 read_only 就万事大吉,却没关掉账号的 SUPER 权限,也没写进配置文件——这两处漏掉任何一项,都等于没设。










