You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL撤销权限报错1147:用户无指定表权限问题排查

问题根源与解决方案

核心原因

MySQL的权限系统采用层级化设计,权限分为全局级(*.*)、数据库级(db.*)、表级(db.table)等多个层级,且遵循以下关键规则:

  1. 高权限层级会自动覆盖低层级权限(比如全局SELECT权限会让用户拥有所有数据库/表的查询权限)
  2. REVOKE操作仅能撤销显式授予的同层级权限,无法撤销通过高权限层级继承而来的低层级权限

你给JOHN@localhost授予的是全局SELECT权限(GRANT SELECT ON *.* TO JOHN@localhost),此时MySQL仅在全局权限表中添加一条记录,不会为每个数据库/表生成单独的权限条目。当你尝试撤销sakila.actor表的权限时,由于该用户从未被显式授予过这个表级的SELECT权限,MySQL找不到对应的权限记录,因此抛出报错:

Error Code: 1147. There is no such grant defined for user 'JOHN' on host 'localhost' on table 'actor'

单独授予sakila.*权限后依然报错的原因同理:此时用户同时拥有全局和数据库级权限,但sakila.actor的访问权限还是来自这两个层级的继承,没有单独的表级权限条目,所以REVOKE仍无法找到对应记录。只有当你显式执行GRANT SELECT ON sakila.actor TO JOHN@localhost后,MySQL才会在表级权限表中生成这条记录,此时REVOKE才能生效。

正确处理方式

如果需要限制用户访问特定表,不能基于全局权限直接撤销,必须先收回高权限层级,再显式授予用户需要的权限:

  1. 先收回全局SELECT权限
REVOKE SELECT ON *.* FROM JOHN@localhost;
  1. 显式授予用户允许访问的所有数据库/表权限,排除需要限制的表
    比如,允许用户访问除sakila.actor外的所有表:
-- 授予所有数据库的查询权限
GRANT SELECT ON *.* TO JOHN@localhost;
-- 收回sakila库的权限,生成数据库级权限条目
REVOKE SELECT ON sakila.* FROM JOHN@localhost;
-- 重新授予sakila库权限,再撤销指定表的权限
GRANT SELECT ON sakila.* TO JOHN@localhost;
REVOKE SELECT ON sakila.actor FROM JOHN@localhost;

内容的提问来源于stack exchange,提问作者Hasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:42:04