navicat无真正只读模式,界面“read only”勾选或team viewer角色不拦截delete/update;真正只读必须由数据库账号权限控制,需手动执行grant select on db.table to 'user'@'ip'并显式revoke写权限,且mysql 8.0.29前须flush privileges。

Navicat SQL编辑器里没有真正的“只读模式”
勾选连接设置里的“Read Only”或把成员设为 Team Viewer,**完全不拦 DELETE/UPDATE**。Navicat 不会拦截你手写的 SQL,它只管界面操作权限(比如改密码、保存查询)。真正起作用的只读,必须由数据库账号权限决定——而且得手动配,不能靠向导。
必须在 MySQL 里执行 GRANT + REVOKE 才算生效
Navicat 的「新建用户」向导只能给 mydb.* 这种库级 SELECT,但生产环境往往只要查 2–3 张表。粗放授权等于埋雷。
- 正确做法是手写:
GRANT SELECT ON mydb.report_log TO 'analyst'@'10.20.30.45' - 紧接着显式收回写权限:
REVOKE INSERT, UPDATE, DELETE, DROP, CREATE, ALTER ON mydb.* FROM 'analyst'@'10.20.30.45' - MySQL 8.0.29 之前必须加:
FLUSH PRIVILEGES,否则权限不加载 -
'host'填的是客户端 IP,不是数据库服务器地址;填'%'就等于开放公网,生产严禁
连接生产库后第一件事:关自动提交 + 开安全更新
即使账号已是只读,也建议每次新开标签页连生产库时,先运行这两句:
SET SQL_SAFE_UPDATES = 1; SET AUTOCOMMIT = 0;
前者拦截无 WHERE 或不走索引的 DELETE/UPDATE,后者让所有 DML 进入事务暂存状态,出错可立刻 ROLLBACK。注意:SET AUTOCOMMIT = 0 只对当前会话有效,关掉标签页就失效。
TRUNCATE 和 DROP 永远无法回滚,权限也拦不住
这是最容易被忽略的硬伤:
-
TRUNCATE TABLE和DROP TABLE不进事务日志,执行即生效,AUTOCOMMIT和触发器都无效 - 只读账号虽没
DROP权限,但如果你用的是有权限的账号(比如 DBA 账号临时连上去查数据),一句误操作就不可逆 - 云数据库(如阿里云 RDS)上,
read_only=ON是实例级开关,需控制台操作,SET GLOBAL直接被拒绝
所以,防误删不能只靠“只读”,得靠流程:固定账号、限定 IP、禁用高危语句、加审计日志,再配上人盯操作习惯。











