MySQL回收权限必须显式指定目标权限与粒度,不可依赖“先全撤再重授”,否则会导致权限空窗、角色权限遗漏、细粒度权限残留及GRANT OPTION未清除等风险;需结合SHOW GRANTS验证并重连生效。
不能靠“先撤 ALL 再重授”来精准回收部分权限——这会引入权限空窗、并发风险和隐式覆盖
REVOKE ALL PRIVILEGES 会清掉所有显式授予的权限,但不保证“干净”
执行
后,该用户在
粒度上的所有权限(如 SELECT、INSERT、PROCESS、RELOAD)都会被移除。但要注意:
如果用户还通过角色(
)继承了权限,这条语句完全不影响角色所带的权限
如果用户在更细粒度上还有独立授权(比如
),而你只撤了
,那这张表的 SELECT 权限依然存在
撤销后立即执行
,中间存在毫秒级无权限窗口——已有连接可能报错,新连接若在重授前建立,会因无任何权限(连 USAGE 都还在)而只能登录、无法做任何操作
想只收回某几个权限?必须显式写出来,别绕弯
例如:用户当前有
,你想只收回
和
,正确做法是:
不是先
,再
后者多出两步、两次网络往返、一次潜在权限丢失;且若重授语句漏写某个权限(比如少写了
),就真丢了
尤其在自动化脚本里,“先全撤再重授”极易因变量拼接错误或权限列表未同步导致权限误删
GRANT OPTION 和 ALL PRIVILEGES 是分离的,必须一起处理
明确不包含
。如果你只执行:
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
→
还在
该用户仍能对别人执行
,等于留了个活口
真正安全的做法是始终带上
:
如果只想收部分权限但保留转授权能力,也得显式保留:
—— 不动
即可
验证比执行更重要,SHOW GRANTS 不等于实时生效
执行
后立刻跑
,看到输出里没了目标权限,不代表已生效:
旧连接仍持有原权限缓存,需断开重连才体现变化
若用的是连接池(如 HikariCP、Druid),得触发连接重建或等待连接超时释放
查的是权限元数据,不是运行时状态;它告诉你“系统记着你该有什么”,但不反映“当前会话实际能做什么”
最稳妥验证方式:新开一个客户端,用该用户登录,执行对应操作(如
)看是否报
真正麻烦的从来不是语法写错,而是以为撤掉了、其实没生效,或者撤得太狠、忘了角色和细粒度授权的存在。MySQL 的权限模型是叠加的,不是覆盖的——你删掉一层,底下还有好几层可能托着它。
REVOKE ALL PRIVILEGES, GRANT OPTION ON *.* FROM 'u1'@'%'*.*ROLESELECT ON sales.orders*.*GRANT SELECT ON *.* TO 'u1'@'%'SELECT, INSERT, UPDATE, DELETE, CREATECREATEDELETEREVOKE CREATE, DELETE ON *.* FROM 'u1'@'%'REVOKE ALL PRIVILEGES ON *.* FROM 'u1'@'%'GRANT SELECT, INSERT, UPDATE ON *.* TO 'u1'@'%'UPDATEALL PRIVILEGESGRANT OPTIONREVOKE ALL PRIVILEGES ON *.* FROM 'u1'@'%'GRANT OPTIONGRANTGRANT OPTIONREVOKE ALL PRIVILEGES, GRANT OPTION ON *.* FROM 'u1'@'%'REVOKE CREATE, DROP ON *.* FROM 'u1'@'%';GRANT OPTIONREVOKESHOW GRANTS FOR 'u1'@'%'SHOW GRANTSCREATE TABLE test(a INT)ERROR 1142 (42000): CREATE command denied