15.7.1.8 撤销语句
REVOKE [IF EXISTS]
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
FROM user_or_role [, user_or_role] ...
[IGNORE UNKNOWN USER]
REVOKE [IF EXISTS] ALL [PRIVILEGES], GRANT OPTION
FROM user_or_role [, user_or_role] ...
[IGNORE UNKNOWN USER]
REVOKE [IF EXISTS] PROXY ON user_or_role
FROM user_or_role [, user_or_role] ...
[IGNORE UNKNOWN USER]
REVOKE [IF EXISTS] role [, role ] ...
FROM user_or_role [, user_or_role ] ...
[IGNORE UNKNOWN USER]
user_or_role: {
user (see Section 8.2.4, “Specifying Account Names”)
| role (see Section 8.2.5, “Specifying Role Names”
}
REVOKE
语句允许系统管理员撤销权限和角色,可以撤销用户账户和角色的权限。
有关权限的级别、可接受的priv_type
、priv_level
和object_type
值,以及指定用户和密码的语法,请参见第15.7.1.6节,“GRANT Statement”。
有关角色的信息,请见第8.2.10节,“Using Roles”。
当read_only
系统变量启用时,REVOKE
需要CONNECTION_ADMIN
或SUPER
特权(或弃用的SUPER
特权),此外还需要任何其他所需的权限,见下文讨论。
所有支持REVOKE
的形式都支持IF EXISTS
和IGNORE UNKNOWN USER
选项。没有这些修改时,REVOKE
将成功或回滚,并且在所有命名用户和角色的语句中没有效果;语句将在成功时写入二进制日志。IF EXISTS
和IGNORE UNKNOWN USER
的确切效果将在本节后面讨论。
每个账户名使用第8.2.4节,“Specifying Account Names”中描述的格式。每个角色的名称使用第8.2.5节,“Specifying Role Names”中描述的格式。例如:
REVOKE INSERT ON *.* FROM 'jeffrey'@'localhost';
REVOKE 'role1', 'role2' FROM 'user1'@'localhost', 'user2'@'localhost';
REVOKE SELECT ON world.* FROM 'role3';
账户或角色的主机名称部分,如果省略,默认为'%'
。
要使用REVOKE
语句的第一种语法,你必须拥有GRANT OPTION
特权,并且你必须拥有要撤销的权限。
要撤销所有权限,请使用第二种语法,这将删除所有全局、数据库、表、列和存储程序的权限:
REVOKE ALL PRIVILEGES, GRANT OPTION
FROM user_or_role [, user_or_role] ...
REVOKE ALL PRIVILEGES, GRANT OPTION
不撤销任何角色。
要使用REVOKE
语句的第二种语法,你必须拥有全局CREATE USER
特权,或者UPDATE
特权以mysql
系统架构。
语法规则是,REVOKE
关键字后跟随一个或多个角色名称,使用 FROM
子句指示要从哪些用户或角色中撤销角色。
以下是 IF EXISTS
和 IGNORE UNKNOWN USER
选项的效果:
-
IF EXISTS
表示,如果目标用户或角色存在,但没有找到任何原因的权限或角色,则会出现警告;如果没有找到任何名为的权限或角色,该语句无效。否则,REVOKE
执行正常;如果用户不存在,语句会出现错误。示例:在数据库
test
中的表t1
中,我们执行以下语句,结果如下。mysql> CREATE USER jerry@localhost; Query OK, 0 rows affected (0.01 sec) mysql> REVOKE SELECT ON test.t1 FROM jerry@localhost; ERROR 1147 (42000): There is no such grant defined for user 'jerry' on host 'localhost' on table 't1' mysql> REVOKE IF EXISTS SELECT ON test.t1 FROM jerry@localhost; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 1147 Message: There is no such grant defined for user 'jerry' on host 'localhost' on table 't1' 1 row in set (0.00 sec)
IF EXISTS
使得错误降级为警告,即使权限或角色不存在,或者语句尝试将其分配到错误的级别。 -
如果
REVOKE
语句包括IGNORE UNKNOWN USER
,语句会出现警告,因为目标用户或角色在语句中命名但找不到;如果语句中没有找到任何目标,REVOKE
执行成功,但无实际效果。否则,语句执行正常,尝试撤销目标用户或角色未分配的权限将出现错误,正如预期那样。示例(继续上一个示例):
mysql> DROP USER IF EXISTS jerry@localhost; Query OK, 0 rows affected (0.01 sec) mysql> REVOKE SELECT ON test.t1 FROM jerry@localhost; ERROR 1147 (42000): There is no such grant defined for user 'jerry' on host 'localhost' on table 't1' mysql> REVOKE SELECT ON test.t1 FROM jerry@localhost IGNORE UNKNOWN USER; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 3162 Message: Authorization ID jerry does not exist. 1 row in set (0.00 sec)
-
IF EXISTS
和IGNORE UNKNOWN USER
的组合意味着REVOKE
永远不会出现未知目标用户或角色或未分配或不可用的权限的错误,语句在这种情况下成功;从现有目标用户或角色中删除角色或权限,每当可能时执行,任何撤销操作都将出现警告并执行为NOOP
。示例(继续上一个示例):
# No such user, no such role mysql> DROP ROLE IF EXISTS Bogus; Query OK, 0 rows affected, 1 warning (0.02 sec) mysql> SHOW WARNINGS; +-------+------+----------------------------------------------+ | Level | Code | Message | +-------+------+----------------------------------------------+ | Note | 3162 | Authorization ID 'Bogus'@'%' does not exist. | +-------+------+----------------------------------------------+ 1 row in set (0.00 sec) # This statement attempts to revoke a nonexistent role from a nonexistent user mysql> REVOKE Bogus ON test FROM jerry@localhost; ERROR 3619 (HY000): Illegal privilege level specified for test # The same, with IF EXISTS mysql> REVOKE IF EXISTS Bogus ON test FROM jerry@localhost; ERROR 1147 (42000): There is no such grant defined for user 'jerry' on host 'localhost' on table 'test' # The same, with IGNORE UNKNOWN USER mysql> REVOKE Bogus ON test FROM jerry@localhost IGNORE UNKNOWN USER; ERROR 3619 (HY000): Illegal privilege level specified for test # The same, with both options mysql> REVOKE IF EXISTS Bogus ON test FROM jerry@localhost IGNORE UNKNOWN USER; Query OK, 0 rows affected, 2 warnings (0.01 sec) mysql> SHOW WARNINGS; +---------+------+--------------------------------------------+ | Level | Code | Message | +---------+------+--------------------------------------------+ | Warning | 3619 | Illegal privilege level specified for test | | Warning | 3162 | Authorization ID jerry does not exist. | +---------+------+--------------------------------------------+ 2 rows in set (0.00 sec)
在 mandatory_roles
系统变量值中命名的角色不能被撤销。使用 IF EXISTS
和 IGNORE UNKNOWN USER
一起在语句中尝试删除强制性权限时,通常出现的错误将降级为警告;语句执行成功,但不做任何更改。
撤销的角色立即影响任何从中撤销的用户账户,以便在当前会话中执行的下一个语句中调整该账户的权限。
撤销角色撤销该角色本身,而不是它所代表的权限。假设账户被授予一个包含特定权限的角色,并且也被授予该权限或另一个包含该权限的角色。在这种情况下,账户仍然拥有该权限,即使第一个角色被撤销。例如,如果账户被授予两个包含 SELECT
的角色,该账户仍然可以选择在任何一个角色被撤销后。
REVOKE ALL ON *.*
(在全局级别) 撤销了所有授予的静态全局权限和所有授予的动态权限。
撤销的权限,如果授予了但服务器不知道,可以撤销,并且会发出警告。这可能会在动态权限的情况下发生。例如,动态权限可以在组件安装时授予,但是如果该组件随后卸载,权限将被卸载,但是拥有该权限的账户仍然拥有该权限,可以撤销该权限。
REVOKE
删除权限,但是不删除 mysql.user
系统表中的行。要完全删除用户账户,请使用 DROP USER
。请参阅 Section 15.7.1.5, “DROP USER Statement”。
如果授权表中包含混合大小写数据库或表名的权限行,并且 lower_case_table_names
系统变量设置为非零值,REVOKE
无法撤销这些权限。在这种情况下,需要直接操作授权表。 (GRANT
不会在设置 lower_case_table_names
时创建这样的行,但是可能已经在设置变量前创建了这些行。该变量只能在初始化服务器时配置。)
成功执行在 mysql 程序中的 REVOKE
将响应 Query OK, 0 rows affected
。要确定操作后剩余的权限,请使用 SHOW GRANTS
。请参阅 Section 15.7.7.22, “SHOW GRANTS Statement”。