drop user仅删除mysql.user表记录,不清理mysql.db等表中的残留权限;需手动执行delete并flush privileges;要求create user或delete权限;账号名必须带完整host;mysql 8.0+需先解除角色绑定。

DROP USER 会直接删掉账号,但权限可能残留
MySQL 的 DROP USER 确实是删除账号的正规方式,但它只清理 mysql.user 表里的记录,不自动回收该用户在其他权限表(比如 mysql.db、mysql.tables_priv)中残留的授权条目。如果之前用 GRANT 给过库级或表级权限,删用户后这些权限记录还在,下次用同名用户重建时可能意外继承旧权限。
- 执行前先查残留权限:
SELECT * FROM mysql.db WHERE User = 'username';
- 手动清理更稳妥:
DELETE FROM mysql.db WHERE User = 'username';<br>DELETE FROM mysql.tables_priv WHERE User = 'username';<br>FLUSH PRIVILEGES;
- MySQL 5.7+ 支持
DROP USER IF EXISTS,避免因用户不存在报错,但依然不解决残留问题
root 权限不足时 DROP USER 会失败
只有拥有 CREATE USER 或 DELETE 权限(针对 mysql 库)的账号才能执行 DROP USER。普通 DBA 账号即使能连上,也可能卡在权限校验这步,报错:ERROR 1045 (28000): Access denied for user ... (using password: YES) 或更具体的 ERROR 1227 (42501): Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation。
- 确认当前账号权限:
SHOW GRANTS FOR CURRENT_USER;
- 必须看到
GRANT CREATE USER ON *.*或等效的GRANT DELETE ON mysql.* - 如果权限不够,别硬试,找有
SUPER或SYSTEM_USER权限的人操作,或者临时提权(不推荐生产环境)
账号名带 host 部分必须完全匹配
MySQL 把 'user'@'host' 当作完整账号标识。删 'app'@'192.168.1.%' 时,写成 DROP USER 'app' 或 DROP USER 'app'@'%' 都不会生效,也不会报错——它就当没这回事,静默跳过。
- 查准账号全名:
SELECT User, Host FROM mysql.user WHERE User = 'app';
- 删除必须带 host:
DROP USER 'app'@'192.168.1.%';
- host 是空字符串(
'')或localhost都不能省略,哪怕看起来一样
MySQL 8.0+ 的角色机制让 DROP USER 更复杂
8.0 引入角色(ROLE),如果被删用户是某个角色的成员(SET DEFAULT ROLE ... TO 'user'@'host'),或本身是个角色,DROP USER 会失败并报错:ERROR 3725 (HY000): Cannot drop a role that is granted to other roles or users。
- 先查角色关系:
SELECT * FROM mysql.role_edges WHERE TO_HOST = 'host' AND TO_USER = 'user';
- 解除绑定再删:
REVOKE 'role_name' FROM 'user'@'host';
- 角色本身也要用
DROP ROLE,不能混用DROP USER
实际删账号不是敲一条命令就完事的事,host 匹配、权限残留、角色依赖,三个地方漏一个,轻则删不干净,重则权限失控。尤其在多实例、混合版本(5.7 和 8.0 共存)环境里,得挨个确认清楚。











