禁止DROP DATABASE需REVOKE DROP ON db_name.;CREATE USER和GRANT OPTION必须ON .*收回;ALTER/INDEX/TEMPORARY TABLES等高危权限须单独撤销;权限生效需实测而非仅看SHOW GRANTS。

MySQL 中如何禁止用户执行 DROP DATABASE
直接 revoke DROP 权限即可,但要注意:该权限控制的是「对数据库对象的删除行为」,不是「是否能连上数据库」。如果用户已有 ALL PRIVILEGES ON *.*,必须先收回全局权限再精细化授权。
-
DROP权限作用于数据库级别(ON database_name.*)或全局(ON *.*),不作用于单表;删表靠DROP TABLE,属于另一权限项 - 执行
REVOKE DROP ON `myapp`.* FROM 'appuser'@'%';
后,该用户仍可删表(DROP TABLE)、删视图,只要没被显式 revoke - 若用户是通过角色(ROLE)获得权限,需对角色 revoke,再
SET DEFAULT ROLE刷新生效
禁止 CREATE USER 和 GRANT OPTION 的实操要点
CREATE USER 和 GRANT OPTION 是高危权限,误授会导致权限扩散。它们不能通过 REVOKE ... ON database_name.* 收回,必须在全局粒度操作。
- 执行
REVOKE CREATE USER ON *.* FROM 'devuser'@'%';
才有效;写成ON mydb.*会报错「Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation」 -
GRANT OPTION一旦存在,用户就能把自身拥有的任何权限转授他人,必须显式 revoke:REVOKE GRANT OPTION ON *.* FROM 'reporter'@'10.20.%';
- revoke 后需执行
FLUSH PRIVILEGES;(仅当使用 grant 表直改时才强制需要;常规 revoke 命令自动刷新)
用最小权限原则限制 ALTER、INDEX、CREATE TEMPORARY TABLES
这些权限常被忽略,但组合起来足以让低权用户破坏性能或绕过约束。例如:ALTER 可修改表结构导致应用异常;INDEX 可建冗余索引拖慢写入;CREATE TEMPORARY TABLES 被用于中间计算,但滥用会耗尽 tmpdir 空间。
- 禁用临时表:
REVOKE CREATE TEMPORARY TABLES ON `sales`.* FROM 'etl_user'@'192.168.5.%';
-
INDEX权限独立于CREATE,即使没CREATE权限,有INDEX也能建索引,务必单独 revoke - MySQL 8.0+ 支持按列 revoke,但
ALTER、INDEX等 DDL 权限只能按库或全局控制,无法细化到表或字段
权限变更后验证是否真正生效
别只信 SHOW GRANTS 输出——它显示的是「当前账号被授予的权限语句」,不反映实际运行时权限(比如角色未激活、host 匹配失败、proxy user 干扰等)。
- 用目标用户连接后,手动测试关键操作:
DROP DATABASE test_db;
应返回 ERROR 1044 (42000): Access denied for user... - 检查权限实际生效路径:
SELECT * FROM information_schema.role_table_grants WHERE grantee = "'appuser'@'%'" OR role_in_hierarchy = "'approle'";
- 注意 host 匹配优先级:MySQL 按
'user'@'192.168.1.%'→'user'@'192.168.%'→'user'@'%'顺序匹配,revoke 必须和 grant 时的 host 完全一致
权限回收不是一劳永逸的事,特别是涉及角色、代理用户、或者 MySQL Router / ProxySQL 中间层时,实际生效链路可能比预期多跳。每次 revoke 后,务必用真实连接复现敏感操作。










