不能。REVOKE ALL仅撤销显式授予的权限,不撤销默认USAGE权限及角色继承权限,且不递归生效于新建对象,需FLUSH PRIVILEGES刷新并用新连接验证。

REVOKE ALL 能否真正撤销所有权限
不能。MySQL 的 REVOKE ALL 只撤销当前显式授予的权限,不触碰系统默认权限(比如 USAGE),也不影响通过角色继承来的权限。它更像“撤回你亲手给的”,而不是“清零”。如果你看到用户还能连上、还能执行 SELECT DATABASE() 或者查 information_schema,那大概率就是 USAGE 还在——这是 MySQL 默认赋予每个账号的基础连接权。
实操建议:
- 先用
SHOW GRANTS FOR 'user'@'host';看清当前到底有哪些权限,别猜 -
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'host';是标准写法,缺一不可;漏掉GRANT OPTION,下次别人再给你授予权限时可能绕过控制 - 如果用户是通过角色获得权限(MySQL 8.0+),必须单独对角色执行
REVOKE,或直接DROP ROLE
撤销后用户仍能登录?检查 USAGE 权限
是的,USAGE 是一个“空权限”:不赋予任何操作能力,但允许建立连接。MySQL 创建用户时(比如用 CREATE USER)会自动附带 USAGE,而 REVOKE ALL 不动它。所以撤销完权限,用户依然能 mysql -u user -p 登录,只是进库后执行任何 DML/DCL 都报 ERROR 1142 (42000)。
实操建议:
- 要彻底禁止访问,得显式收回连接权:
REVOKE USAGE ON *.* FROM 'user'@'host'; - 但注意:MySQL 不允许只留
USAGE之外的权限而不留USAGE;反过来,删掉USAGE后,该账号将完全无法认证登录 - 生产环境慎用直接删
USAGE,建议优先用DROP USER彻底移除账号
REVOKE ALL 对数据库/表级权限是否递归生效
不递归。MySQL 的权限是分层的,REVOKE ALL ON db.* 只影响该数据库下当前存在的表,不会自动覆盖后续新建的表;同理,REVOKE ALL ON *.* 不影响已授予的具体表(如 db.tbl)或列级权限。
实操建议:
- 若需确保某用户对整个实例“无感”,必须逐层清理:
REVOKE ALL ON *.*+REVOKE ALL ON db1.*+REVOKE ALL ON db1.tbl1(如有) - MySQL 8.0.16+ 支持
REVOKE ALL ON ALL SCHEMAS.*,但仅限 schema 级,仍不覆盖表/列/例程 - 权限变更不实时生效:需执行
FLUSH PRIVILEGES;,否则旧连接可能缓存权限状态
撤销权限后应用报错 ERROR 1045 或 ERROR 1142 怎么快速定位
ERROR 1045 (28000) 是认证失败(用户名/密码/主机不匹配),和权限无关;真权限问题几乎全是 ERROR 1142 (42000),比如 SELECT command denied to user。但很多人混淆这两者,浪费排查时间。
实操建议:
- 先确认错误码:
ERROR 1142才是权限不足;ERROR 1045要查mysql.user表里Host和连接来源是否一致 - 用
SELECT * FROM mysql.tables_priv WHERE User='user' AND Host='host';直接查权限存储表,比SHOW GRANTS更底层、更准 - 注意大小写:MySQL 权限表中
User和Host匹配严格区分大小写(尤其在 Linux 上)
最常被忽略的一点:权限撤销后,已存在的长连接不会立即失效,直到它下一次执行语句时才校验——所以测试务必用新连接,别在旧 shell 里反复重试。


















