mysql无自动锁死数据库机制,可靠只读需三措并举:设read_only=on、收窄用户权限、会话级set session read_only=on,并须回收super或system_variables_admin等高危权限。

MySQL 没有“自动锁死数据库”的机制
MySQL 本身不提供“数据库级自动锁死”功能,所谓“锁死”通常是误读或混淆了 READ ONLY 模式、FLUSH TABLES WITH READ LOCK、或者安全模式(--safe-mode 不存在,实际是 --safe-user-create 等旧参数,现代 MySQL 已弃用)等概念。真正能限制写入的,只有明确配置的只读控制或权限收窄。
让数据库“事实只读”的三种可靠方式
想阻止任何用户执行 INSERT/UPDATE/DELETE,必须从权限、实例配置或会话行为三处下手,不能依赖模糊的“安全模式”:
-
全局只读开关:设
read_only=ON(需 SUPER 权限),但root或带SYSTEM_VARIABLES_ADMIN权限的用户仍可绕过;普通用户写操作直接报错ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement -
权限粒度控制:对业务账号撤销
INSERT、UPDATE、DELETE、DROP等权限,仅保留SELECT;注意GRANT OPTION必须收回,否则用户可自行授予权限 -
会话级只读:连接后执行
SET SESSION read_only = ON,仅影响当前连接;适合应用层主动控制,但无法防止其他连接写入
为什么 --safe-mode 不是你要找的东西
MySQL 命令行客户端(mysql CLI)有个 --safe-updates(或 -U)选项,它不是服务端参数,也不锁库——它只是客户端强制要求 UPDATE/DELETE 必须带 WHERE 条件或使用主键/索引,避免全表误删。服务端压根不感知这个开关。
- 错误现象:
mysql -U -u user db连上后执行DELETE FROM logs;→ 报错ERROR 1175 (HY000): You are using safe update mode... - 它不影响
INSERT、不阻断其他客户端、不修改服务器状态 - 服务端启动时传
--safe-mode会被忽略,mysqld 启动会直接报Unknown option '--safe-mode'
最容易被忽略的权限漏点:SUPER 和 SYSTEM_VARIABLES_ADMIN
即使你设了 read_only=ON,只要用户拥有 SUPER(MySQL 5.7 及以前)或 SYSTEM_VARIABLES_ADMIN + CONNECTION_ADMIN(MySQL 8.0+),就能随时关掉只读:
SET GLOBAL read_only = OFF;
所以真正“锁死”,必须同步检查并回收这些高危权限:
- 查用户权限:
SHOW GRANTS FOR 'app_user'@'%'; - 回收权限(MySQL 8.0+):
REVOKE SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN ON *.* FROM 'app_user'@'%'; - 注意:
read_only对temp_table、information_schema写入无效,这类操作仍可能成功
事情说清了就结束










