MySQL从库仍可写因read_only=ON未生效,主因是高权限用户绕过、启动前未配置及云RDS限制;需在my.cnf设read_only=ON与super_read_only=ON,确认复制状态正常,并回收非必要写权限。

MySQL 从库为什么还是能写?read_only=ON 不生效的常见原因
根本问题不在配置本身,而在于权限和启动时机。即使你执行了 SET GLOBAL read_only = ON,如果当前连接用户拥有 SUPER 或 REPLICATION CLIENT 权限(尤其是 root),依然可以绕过限制写入数据。
-
read_only是会话级防护,不是强制访问控制——它只拒绝普通用户的写操作,不拦高权限用户 - 必须在从库启动前,就在配置文件中设置
read_only=ON,否则主从同步线程(SQL_THREAD)可能因权限不足无法回放 relay log - 某些云厂商 RDS 默认关闭
read_only,且禁止修改该参数,得走控制台开关或申请白名单
配置只读从库的关键三步:启动参数、复制状态、权限收紧
只靠 SQL 命令临时设 read_only 不可靠,必须组合落地。
- 在
my.cnf的[mysqld]段落里加:read_only=ON和super_read_only=ON(MySQL 5.7.8+ 才有,能真正锁死SUPER用户的写权限) - 确认复制正常运行:
SHOW SLAVE STATUS\G中Slave_IO_Running和Slave_SQL_Running都是Yes;若为Connecting,检查master_host、证书或网络连通性 - 回收非必要写权限:
REVOKE INSERT, UPDATE, DELETE, DROP, CREATE ON *.* FROM 'backup_user'@'%';,只保留SELECT和REPLICATION CLIENT
备份节点被误写后的快速识别与止损
一旦发现从库数据和主库不一致,别急着重搭,先定位是否真被写入。
- 查最近写操作:
SELECT * FROM performance_schema.events_statements_summary_by_digest WHERE DIGEST_TEXT LIKE '%INSERT%' OR DIGEST_TEXT LIKE '%UPDATE%' ORDER BY LAST_SEEN DESC LIMIT 5; - 看 binlog 是否开启(只读从库不该有自己产生的 binlog):
SHOW VARIABLES LIKE 'log_bin';应为OFF;若为ON,立即关掉并重启,否则可能把误写同步给下游 - 对比主从 GTID:
SELECT @@global.gtid_executed;在主从上分别执行,结果不一致就说明从库执行了额外事务
只读备份节点上线后还要盯什么?
配置完只是起点,持续可用取决于几个容易被忽略的细节。
-
relay_log_purge=ON必须开启,否则 relay log 占满磁盘会导致 SQL 线程停止,从库“静默脱同步”而不报错 - 监控
Seconds_Behind_Master要结合SQL_Delay看——如果设置了延迟复制,这个值长期非零是正常的,不能直接当故障告警 - 定期用
pt-table-checksum校验主从一致性,尤其在大表 DDL 后;不要只依赖SHOW SLAVE STATUS的Exec_Master_Log_Pos
最麻烦的不是配不配得上,而是配完没人看 Relay_Log_Space 和 Retrieved_Gtid_Set 这两个值——它们一涨一停,往往就是备份节点开始“失联”的第一分钟。


















