删库不等于删权限,必须先用REVOKE撤销test库相关授权(含GRANT OPTION),再踢掉活跃连接,最后DROP DATABASE;残留权限存于mysql.db表,需SELECT User,Host,Db FROM mysql.db WHERE Db='test'或'TEST'核查。

确认 test 库是否还被用户授权访问
很多人以为删掉 test 数据库就等于清除了权限,其实不是。权限记录存在 mysql.db 表里,哪怕库已不存在,用户仍可能保有 SELECT ON test.* 这类残留授权,下次建同名库时会自动生效。
执行这条语句查清现状:
SELECT User, Host, Db FROM mysql.db WHERE Db = 'test' OR Db = 'TEST';
注意大小写:MySQL 5.7 默认区分数据库名大小写(除非 lower_case_table_names=1),所以 'test' 和 'TEST' 要分别检查。
- 若返回结果,说明至少有一个用户还拥有对
test库的显式权限 - 若返回空,不代表绝对安全——还要看有没有用户被授予了
ALL PRIVILEGES ON *.*,那自然包含test
用 REVOKE 逐层回收 test 相关权限
直接删库不等于删权限,必须用 REVOKE 主动撤销。错误做法是只删 mysql.db 行或跳过 FLUSH PRIVILEGES;正确顺序是:
- 先撤销具体库级权限:
REVOKE ALL PRIVILEGES ON `test`.* FROM 'user1'@'%'; - 再检查并撤销该用户是否在全局层级也有权限:
REVOKE ALL PRIVILEGES ON *.* FROM 'user1'@'%'; - 如果当初授权带
WITH GRANT OPTION,还得加一句:REVOKE GRANT OPTION ON `test`.* FROM 'user1'@'%';
特别注意:REVOKE 必须严格匹配当初 GRANT 的范围。比如当初是 GRANT SELECT ON test.t1 TO ...,就不能用 ON test.* 去撤销,否则报错 ERROR 1141。
删库前确保没有活跃连接依赖 test
DROP DATABASE test; 看似简单,但若当前有连接正用 USE test; 或正在查询 test 下的表,命令会卡住甚至失败(尤其在事务中)。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
安全做法是先踢掉相关连接:
SELECT CONCAT('KILL ',id,';') FROM information_schema.processlist WHERE db = 'test';把输出结果复制执行(或用脚本批量处理)。之后再删库:
DROP DATABASE IF EXISTS test;
- MySQL 5.7 不会自动删
mysql.db中对应记录,所以必须先REVOKE,再DROP DATABASE - 删完立刻验证:
SHOW DATABASES LIKE 'test';应无返回
别漏掉 root 或其他高权限用户的 test 权限
很多环境里,root@localhost 被默认授予了 ALL PRIVILEGES ON *.*,它天然能操作 test。但这不是问题——问题在于,如果你后来又给普通用户也开了 *.*,那就等于把 test 的入口敞开了。
检查高风险授权:
SELECT User, Host, Grant_priv FROM mysql.user WHERE Grant_priv = 'Y' OR Super_priv = 'Y';
- 非必要不给普通账号
Grant_priv,否则它自己就能开test权限 - 如果发现
'appuser'@'%' GRANT OPTION ON *.*,立刻收回:REVOKE GRANT OPTION ON *.* FROM 'appuser'@'%';
最后执行 FLUSH PRIVILEGES; —— MySQL 5.7 部分补丁版本存在权限缓存延迟,这一步不能省。
真正容易被忽略的点是:权限撤销后,用户仍可能通过角色(role)间接获得 test 访问能力。MySQL 5.7 不支持角色,但如果你用了兼容层或外部权限代理,得额外检查角色绑定关系。

















