MySQL 从库设为 read_only=ON 是否真能防误删? 这个设置能拦截绝大多数“手滑”操作,但并非绝对安全。它能有效阻止普通用户执行 DELETE、UPDATE、INSERT 及 DROP 等 DML 和 DDL 操作。然而,关键前提是操作用户不能是拥有 super 或 SYSTEM_VA
这个设置能拦截绝大多数“手滑”操作,但并非绝对安全。它能有效阻止普通用户执行 DELETE、UPDATE、INSERT 及 DROP 等 DML 和 DDL 操作。然而,关键前提是操作用户不能是拥有 super 或 SYSTEM_VARIABLES_ADMIN 等高权限的账号。一旦高权限账号登录,read_only 的防线就会被绕过,写入操作仍可进行。
这也解释了运维中常见的两个现象:设置了 read_only=ON 后,用 root 账号登录仍能成功删表;或在主从切换后,从库未自动恢复只读状态,导致后续数据写入污染。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
要避免这些问题,需关注以下细节:
read_only 是会话级变量,必须全局生效:SET GLOBAL read_only = ON;my.cnf 或 my.ini)的 [mysqld] 段落中添加:read_only = ON。read_only 不够,必须确认 super_read_only=ON 也已启用,否则高权限用户仍可写入。
简而言之,read_only 限制普通用户,而 super_read_only 限制包括 root 在内的超级用户。一旦开启 super_read_only,连执行 SET GLOBAL read_only = OFF 也会失败,除非先关闭 super_read_only 本身。
此特性在以下场景中尤为重要:生产环境的从库、专用备份节点、用于审计的数据环境等任何不希望发生意外写入的地方。
启用时需严格遵循顺序:
read_only,再开启 super_read_only。顺序颠倒会导致后者开启失败。SET GLOBAL super_read_only = OFF,再关闭 read_only。super_read_only 变量从 MySQL 5.7.20 版本开始支持。更早版本需依赖严格的权限控制和额外监控告警来弥补。即使开启 read_only,数据库也非完全“只读”。以下几类操作仍可能写入数据,导致从库数据意外变更:
FLUSH LOGS、RESET MASTER。这些命令虽不直接修改业务表,但会破坏二进制日志结构,影响复制一致性。CREATE TEMPORARY TABLE 语句不受 read_only 限制。mysql.user。若登录账号拥有系统表的 UPDATE 权限,操作仍可成功。INSERT 等操作,且未用 READS SQL DATA 等限定符声明为只读,调用时可能产生写入。因此,仅依赖 read_only 参数并不足够。需结合“最小权限原则”:为从库创建专用连接账号,仅授予 SELECT、REPLICATION CLIENT、PROCESS 等必要的只读或监控权限,移除所有 DML 和 DCL 权限。
通过 SHOW VARIABLES LIKE 'read_only' 查看到返回值为 ON 是良好迹象,但不等同于绝对安全。实际情况可能更复杂:该设置可能被临时运维脚本关闭后忘记重新打开;或账号权限未严格限制,留有后门。
如何可靠验证?以下方法较为稳妥:
INSERT INTO test_table VALUES (1);。预期应收到类似 ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement 的错误。root 等高权限账号登录,尝试执行:SET GLOBAL read_only = OFF;。若命令执行成功,则证明 super_read_only 未开启,防线存在漏洞。performance_schema.events_statements_summary_by_user 系统表,查看近期是否有 UPDATE 或 DELETE 等语句记录。真正棘手的是“半只读”状态:配置文件中已设置参数,但 MySQL 启动时因权限或路径问题未能成功加载;或参数被 systemd 服务脚本、其他自动化部署工具意外覆盖。因此,每次相关配置变更后,最稳妥的做法是亲自登录数据库,执行上述写操作测试进行验证,确保万无一失。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述