revoke all privileges, grant option from 'username'@'host'可保留账号并清空显式权限,但不撤销默认usage及角色继承权限,需匹配精确用户名主机名、验证权限、重连生效,并检查残留权限表。

用 REVOKE ALL PRIVILEGES 撤销全部权限
要保留账号但清空所有权限,不能用 DROP USER(它会连账号一起删),必须用 REVOKE。核心命令是:
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'username'@'host';
注意两点:必须同时撤掉 GRANT OPTION,否则用户仍可能给自己授予权限;username 和 host 必须完整匹配,比如 'app'@'192.168.1.%' 写成 'app'@'%' 就无效。
执行前确认权限足够
REVOKE 不是所有人都能跑——你当前登录的账号至少得有全局 CREATE USER 权限,或者对 mysql 库有 UPDATE 权限。否则会报错:
ERROR 1227 (42501): Access denied; you need (at least one of) the CREATE USER privilege(s)
检查自己有没有权限:
SHOW GRANTS FOR CURRENT_USER;
如果没看到 GRANT CREATE USER ON *.* 或类似条目,就别硬试,得换高权限账号操作。
撤销后权限不会立即对已连接会话生效
REVOKE 只影响后续新连接,当前已连上的客户端还能继续执行原有权限范围内的操作,直到断开重连。这点容易被忽略:
- 全局权限(如
SELECT ON *.*)变更只在下次连接时生效 - 库级权限(如
SELECT ON mydb.*)在下一个USE mydb后才应用 - 表级权限变更则从下一条查询开始生效
所以测试是否生效,得新开一个 mysql -u username -p 连接再查 SHOW GRANTS FOR 'username'@'host';,返回结果应只剩 GRANT USAGE ON *.* TO ... —— 这代表账号存在但无任何实际权限。
残留权限表可能未被清理
REVOKE 主要处理 mysql.user、mysql.db、mysql.tables_priv 等系统表,但某些旧版本或异常授权路径(比如直接 INSERT 到权限表)可能导致残留。如果之后重建同名用户却“意外”获得旧权限,就要手动检查:
SELECT * FROM mysql.db WHERE User = 'username';<br>SELECT * FROM mysql.tables_priv WHERE User = 'username';
发现残留记录就删掉,并补上 FLUSH PRIVILEGES;。不过这种情况较少见,日常运维中优先信任 REVOKE 的标准行为。











