生产库权限回收必须在数据库层操作,不能仅依赖应用账号控制;需通过显式回收dml权限、schema权限并精确授予只读权限来实现,且须验证跨库查询、函数调用及事务行为。
生产库权限回收必须走数据库层,不能只靠应用账号控制
应用账号只读 ≠ 数据库账号只读。很多团队改完应用配置就以为安全了,结果开发仍能通过 mysql、psql 或 navicat 直连生产库执行 update。真正有效的回收,得在数据库用户权限层面操作。
常见错误现象:Access denied for user 'dev'@'%' to database 'prod_db' 没出现,但 SELECT 能跑、INSERT 报错——这说明权限没清干净,可能漏掉了 UPDATE/DELETE 的显式拒绝,或残留了 GRANT OPTION。
- 先查清当前权限:
SHOW GRANTS FOR 'dev_user'@'%'; - 回收前务必确认该账号是否被其他服务(如定时任务、旧管理脚本)依赖,避免误杀
- MySQL 8.0+ 建议用角色(
CREATE ROLE+GRANT)统一管理,降级时只需REVOKE role_readonly FROM 'dev_user'@'%';
PostgreSQL 怎么安全地把 dev_user 改成只读
PG 不支持 REVOKE ALL 后再加 SELECT 这种“清空再赋值”逻辑——因为默认 schema(如 public)的 USAGE 权限不回收,用户仍可能创建临时表甚至调用某些函数间接写数据。
正确做法是分三步走,缺一不可:
- 撤掉所有 DML 权限:
REVOKE INSERT, UPDATE, DELETE, TRUNCATE ON ALL TABLES IN SCHEMA public FROM dev_user; - 撤掉 schema 级权限:
REVOKE USAGE ON SCHEMA public FROM dev_user;(否则SELECT可能因无 USAGE 而失败,需后续重授) - 精确授予只读能力:
GRANT USAGE ON SCHEMA public TO dev_user;+GRANT SELECT ON ALL TABLES IN SCHEMA public TO dev_user;
注意:新创建的表不会自动继承权限,要配 ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO dev_user;
MySQL 5.7 和 8.0 权限回收差异在哪
MySQL 5.7 对权限变更不敏感,FLUSH PRIVILEGES 往往被忽略,导致回收后权限仍生效;而 MySQL 8.0 引入了动态权限系统,部分权限(如 SYSTEM_VARIABLES_ADMIN)即使没显式授予,也可能通过角色隐式获得。
关键区别点:
- 5.7 必须执行
FLUSH PRIVILEGES;才能让REVOKE生效;8.0 大多数情况实时生效,但涉及角色时需SET ROLE DEFAULT;清除会话缓存 - 8.0 中
REVOKE SELECT ON prod_db.* FROM 'dev_user'@'%';不会影响视图访问——视图权限独立,得单独REVOKE SELECT ON prod_db.v_user_summary FROM ... - 若用
mysqldump导出时加了--single-transaction,只读账号仍可能触发长事务阻塞,这不是权限问题,但常被误判为“权限没回收好”
回收后怎么验证是否真只读
别信文档,别信同事说“我试过 SELECT 没问题”,得用最接近真实操作的方式测。重点不是“能不能 SELECT”,而是“有没有任何路径能绕过只读限制”。
实操验证建议:
- 用目标账号直连:
mysql -u dev_user -h prod-db -p,然后尝试INSERT INTO users (name) VALUES ('test');—— 必须报ERROR 1142 (42000): INSERT command denied - 检查能否跨库查询:
SELECT COUNT(*) FROM mysql.user;—— 如果能查系统表,说明SELECT权限范围过大,应限定到业务库 - 测试函数调用:
SELECT NOW();允许,但SELECT LOAD_FILE('/etc/passwd');必须拒绝(尤其 MySQL 开启了secure_file_priv时更要确认)
最容易被忽略的是:某些 ORM(如 Django 的 manage.py dbshell)会默认开启 autocommit,但手动 BEGIN; UPDATE ...; 后不 COMMIT,看起来像“没写成功”,其实锁已持住,影响线上事务——权限回收不能只看语法报错,得看行为收敛。










