MySQL中REVOKE执行成功后当前会话权限不立即失效,仅修改系统表,活跃连接仍用旧权限快照;撤销须精确匹配GRANT对象范围,且ALL PRIVILEGES不包含隐式USAGE权限。
MySQL 中 REVOKE 执行成功不代表当前会话权限立刻回收。用户已建立的连接仍保留原有权限,直到重新登录或显式执行 FLUSH PRIVILEGES(但通常不需要)。真正生效依赖于权限缓存刷新机制——MySQL 服务端在用户发起新请求时才校验权限表,而活跃连接不会自动重载。
REVOKE 只修改 mysql.user、mysql.db 等系统表,不主动通知已有连接MySQL 权限是按「权限类型 + 数据库/表名 + 用户@host」三维绑定的。REVOKE 不能模糊匹配,必须精确还原当初 GRANT 的粒度,否则报错 ERROR 1141 (42000): There is no such grant defined for user 'u' on host '%'。

GRANT SELECT ON `mydb`.* TO 'u'@'%' 授予库级权限,就不能用 REVOKE SELECT ON *.* FROM 'u'@'%'
GRANT SELECT(id,name) ON t1 TO 'u'@'%')必须写全列名:REVOKE SELECT(id,name) ON t1 FROM 'u'@'%'
my-db),需写成 REVOKE ALL ON `my-db`.* FROM 'u'@'%'
REVOKE ALL PRIVILEGES ON *.* FROM 'u'@'%' 不会清除 USAGE 权限——这是 MySQL 的默认基础权限,表示“允许连接但无任何操作权”。它不记录在权限表中,也不参与权限计算,所以无法被 REVOKE 显式移除。
USAGE 是隐式存在的,只要用户账号存在,就默认具备该权限DROP USER 'u'@'%' 或 ALTER USER 'u'@'%' ACCOUNT LOCK
SHOW GRANTS FOR 'u'@'%' 会看到 GRANT USAGE ON *.* TO 'u'@'%',但这只是提示,不是真实可撤销项虽然多数情况下 REVOKE 后无需手动刷新,但在某些特殊部署中(如开启 skip-grant-tables 后关闭、或从备份恢复权限表后),权限缓存可能未同步。此时即使 REVOKE 成功,旧权限仍可能被继续使用。
SELECT CURRENT_USER(), USER(); 和尝试受限制操作(如 INSERT INTO restricted_table)FLUSH PRIVILEGES; 强制重载全部权限表,但生产环境慎用——它会锁表并短暂阻塞其他权限变更REVOKE 内部已自动触发局部刷新,FLUSH PRIVILEGES 更多用于修复异常状态REVOKE INSERT, UPDATE ON `sales_db`.`orders` FROM 'analyst'@'192.168.1.%'; REVOKE SELECT (id, status) ON `sales_db`.`orders` FROM 'reporter'@'%';
权限撤销不是“一键清零”,关键在于对象范围、用户标识、连接生命周期三者的严格对应。最容易忽略的是:你以为撤销了,其实只是下次登录才生效;你以为删干净了,其实 USAGE 还在那儿占着位置。