REVOKE命令必须指定ON子句,如REVOKE DELETE ON db.table FROM 'u'@'h';缺失或不匹配将报错或无效,且需与原GRANT语句完全对应。

不能只写 REVOKE DELETE FROM 'u'@'h' —— 缺少 ON database.table 会直接报错,且权限根本没撤掉。
REVOKE DELETE 必须带明确的 ON 子句
MySQL 的 REVOKE 不是“撤销某个权限类型”,而是“撤销某次 GRANT 的逆操作”。当初用 GRANT DELETE ON mydb.users TO 'u1'@'%' 授的权,现在就必须写 REVOKE DELETE ON mydb.users FROM 'u1'@'%' 才生效。
常见错误现象:
-
REVOKE DELETE FROM 'u1'@'%'→ 报错ERROR 1141 (42000): There is no such grant defined... -
REVOKE DELETE ON mydb.* FROM 'u1'@'%'却想撤掉GRANT DELETE ON mydb.t1→ 实际不匹配,权限仍在 - 大小写搞错:比如
mydb.Usersvsmydb.users(受lower_case_table_names设置影响)
如何精准定位该撤哪一层的 DELETE 权限
先查清楚用户到底有哪些 DELETE 权限,再对应回收:
- 用
SHOW GRANTS FOR 'u1'@'%'看当前所有授权语句 - 重点关注含
DELETE和ON的行,例如:GRANT DELETE ON `sales`.* TO 'u1'@'%'或GRANT DELETE ON `hr`.`employees` TO 'u1'@'%' - 如果看到
GRANT ALL PRIVILEGES ON *.*,那 DELETE 是全局的,得用REVOKE DELETE ON *.* FROM 'u1'@'%' - 注意:
REVOKE DELETE ON mydb.*不会撤掉mydb.t1上单独授予的 DELETE,必须分别处理
撤了 DELETE 权限,用户还能删数据吗?
不能默认认为“删了 DELETE 就安全了”——实际还有几条绕过路径:
- 如果用户仍有
DROP权限,可直接删整张表(DROP TABLE不依赖 DELETE) - 如果用户有
ALTER+CREATE,能RENAME TABLE再重建,间接清空数据 -
TRUNCATE TABLE在部分 MySQL 版本中只需DROP权限(不是 DELETE),也可能继续成功 - 若用户拥有存储过程执行权,且过程里含
DELETE语句,权限回收对调用无效
回收后要不要 FLUSH PRIVILEGES
不需要。MySQL 8.0+ 和大多数 5.7 配置下,REVOKE 执行成功即刻生效,权限缓存在内存中已自动刷新。
只有极少数旧配置(如手动修改了 mysql.user 表)才需 FLUSH PRIVILEGES,正常用 REVOKE 语句操作时加它反而多余,还可能掩盖语法错误。
真正容易被忽略的是:权限撤销后,应用连接池里的长连接可能仍带着旧权限上下文跑一段时间,得靠重启连接或等待空闲超时才能彻底失效。


















