Prior to MySQL 8.0.16, it is not possible to grant privileges that apply globally except for certain schemas. 在MySQL 8.0.16之前,除了某些模式外,不可能授予全局适用的特权。As of MySQL 8.0.16, that is possible if the 从MySQL 8.0.16开始,如果启用了partial_revokes
system variable is enabled. partial_revokes
系统变量,这是可能的。Specifically, for users who have privileges at the global level, 具体来说,对于在全局级别拥有权限的用户,partial_revokes
enables privileges for specific schemas to be revoked while leaving the privileges in place for other schemas. partial_revokes
允许撤销特定模式的权限,同时保留其他模式的权限。Privilege restrictions thus imposed may be useful for administration of accounts that have global privileges but should not be permitted to access certain schemas. 因此施加的特权限制可能有助于管理具有全局特权但不应被允许访问某些模式的帐户。For example, it is possible to permit an account to modify any table except those in the 例如,可以允许帐户修改mysql
system schema.mysql
系统模式中的表之外的任何表。
For brevity, 为简洁起见,此处显示的CREATE USER
statements shown here do not include passwords. For production use, always assign account passwords.CREATE USER
语句不包括密码。对于生产使用,始终分配帐户密码。
The partial_revokes
system variable controls whether privilege restrictions can be placed on accounts. partial_revokes
系统变量控制是否可以对帐户施加权限限制。By default, 默认情况下,partial_revokes
is disabled and attempts to partially revoke global privileges produce an error:partial_revokes
被禁用,尝试部分撤销全局权限会产生错误:
mysql>CREATE USER u1;
mysql>GRANT SELECT, INSERT ON *.* TO u1;
mysql>REVOKE INSERT ON world.* FROM u1;
ERROR 1141 (42000): There is no such grant defined for user 'u1' on host '%'
To permit the 要允许REVOKE
operation, enable partial_revokes
:REVOKE
操作,请启用partial_revokes
:
SET PERSIST partial_revokes = ON;
SET PERSIST
sets the value for the running MySQL instance. SET PERSIST
设置正在运行的MySQL实例的值。It also saves the value, causing it to carry over to subsequent server restarts. 它还保存了该值,使其延续到后续的服务器重启。To change the value for the running MySQL instance without having it carry over to subsequent restarts, use the 要更改正在运行的MySQL实例的值而不将其转移到后续重启,请使用GLOBAL
keyword rather than PERSIST
. GLOBAL
关键字而不是PERSIST
。See Section 13.7.6.1, “SET Syntax for Variable Assignment”.请参阅第13.7.6.1节,“变量赋值的SET语法”。
With 启用partial_revokes
enabled, the partial revoke succeeds:partial_revokes
后,部分撤销成功:
mysql>REVOKE INSERT ON world.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+------------------------------------------+ | Grants for u1@% | +------------------------------------------+ | GRANT SELECT, INSERT ON *.* TO `u1`@`%` | | REVOKE INSERT ON `world`.* FROM `u1`@`%` | +------------------------------------------+
SHOW GRANTS
lists partial revokes as REVOKE
statements in its output. SHOW GRANTS
在其输出中将部分撤销作为REVOKE
语句列出。The result indicates that 结果表明,u1
has global SELECT
and INSERT
privileges, except that INSERT
cannot be exercised for tables in the world
schema. u1
具有全局SELECT
和INSERT
权限,但不能对world
模式中的表执行INSERT
。That is, access by 也就是说,u1
to world
tables is read only.u1
对world
表的访问是只读的。
The server records privilege restrictions implemented through partial revokes in the 服务器在mysql.user
system table. mysql.user
系统表中记录通过部分撤销实现的权限限制。If an account has partial revokes, its 如果帐户有部分撤销,则其User_attributes
column value has a Restrictions
attribute:User_attributes
列值具有Restrictions
属性:
mysql>SELECT User, Host, User_attributes->>'$.Restrictions'
FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
+------+------+------------------------------------------------------+ | User | Host | User_attributes->>'$.Restrictions' | +------+------+------------------------------------------------------+ | u1 | % | [{"Database": "world", "Privileges": ["INSERT"]}] | +------+------+------------------------------------------------------+
Although partial revokes can be imposed for any schema, privilege restrictions on the 尽管可以对任何模式实施部分撤销,但作为防止常规帐户修改系统帐户的策略的一部分,对mysql
system schema in particular are useful as part of a strategy for preventing regular accounts from modifying system accounts. mysql
系统模式的特权限制尤其有用。See Protecting System Accounts Against Manipulation by Regular Accounts.请参阅保护系统帐户免受常规帐户的操纵。
Partial revoke operations are subject to these conditions:部分撤销操作受以下条件的约束:
It is possible to use partial revokes to place restrictions on nonexistent schemas, but only if the revoked privilege is granted globally. If a privilege is not granted globally, revoking it for a nonexistent schema produces an error.可以使用部分撤销来对不存在的模式施加限制,但前提是撤销的特权是全局授予的。如果未全局授予特权,则对不存在的模式撤销特权会产生错误。
Partial revokes apply at the schema level only. You cannot use partial revokes for privileges that apply only globally (such as 部分撤销仅适用于架构级别。您不能对仅全局适用的特权(如FILE
or BINLOG_ADMIN
), or for table, column, or routine privileges.FILE
或BINLOG_ADMIN
)或表、列或例程特权使用部分撤销。
In privilege assignments, enabling 在特权分配中,启用partial_revokes
causes MySQL to interpret occurrences of unescaped _
and %
SQL wildcard characters in schema names as literal characters, just as if they had been escaped as \_
and \%
. partial_revokes
会导致MySQL将模式名称中出现的未转义_
和%
SQL通配符解释为文字字符,就像它们被转义为\_
和\%
一样。Because this changes how MySQL interprets privileges, it may be advisable to avoid unescaped wildcard characters in privilege assignments for installations where 因为这会改变MySQL解释特权的方式,所以对于可能启用partial_revokes
may be enabled.partial_revokes
的安装,建议在特权分配中避免使用未转义的通配符。
As mentioned previously, partial revokes of schema-level privileges appear in 如前所述,模式级特权的部分撤销以SHOW GRANTS
output as REVOKE
statements. REVOKE
语句的形式出现在SHOW GRANTS
输出中。This differs from how 这与SHOW GRANTS
represents “plain” schema-level privileges:SHOW GRANTS
表示“普通”模式级权限的方式不同:
When granted, schema-level privileges are represented by their own 当被授予时,模式级特权在输出中由它们自己的GRANT
statements in the output:GRANT
语句表示:
mysql>CREATE USER u1;
mysql>GRANT UPDATE ON mysql.* TO u1;
mysql>GRANT DELETE ON world.* TO u1;
mysql>SHOW GRANTS FOR u1;
+---------------------------------------+ | Grants for u1@% | +---------------------------------------+ | GRANT USAGE ON *.* TO `u1`@`%` | | GRANT UPDATE ON `mysql`.* TO `u1`@`%` | | GRANT DELETE ON `world`.* TO `u1`@`%` | +---------------------------------------+
When revoked, schema-level privileges simply disappear from the output. They do not appear as 当被撤销时,模式级权限会从输出中消失。它们不会以REVOKE
statements:REVOKE
语句的形式出现:
mysql>REVOKE UPDATE ON mysql.* FROM u1;
mysql>REVOKE DELETE ON world.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+--------------------------------+ | Grants for u1@% | +--------------------------------+ | GRANT USAGE ON *.* TO `u1`@`%` | +--------------------------------+
When a user grants a privilege, any restriction the grantor has on the privilege is inherited by the grantee, unless the grantee already has the privilege without the restriction. 当用户授予特权时,授予人对特权的任何限制都由受让人继承,除非受让人已经拥有没有限制的特权。Consider the following two users, one of whom has the global 考虑以下两个用户,其中一个具有全局SELECT
privilege:SELECT
权限:
CREATE USER u1, u2; GRANT SELECT ON *.* TO u2;
Suppose that an administrative user 假设管理用户admin
has a global but partially revoked SELECT
privilege:admin
具有全局但部分撤销的SELECT
权限:
mysql>CREATE USER admin;
mysql>GRANT SELECT ON *.* TO admin WITH GRANT OPTION;
mysql>REVOKE SELECT ON mysql.* FROM admin;
mysql>SHOW GRANTS FOR admin;
+------------------------------------------------------+ | Grants for admin@% | +------------------------------------------------------+ | GRANT SELECT ON *.* TO `admin`@`%` WITH GRANT OPTION | | REVOKE SELECT ON `mysql`.* FROM `admin`@`%` | +------------------------------------------------------+
If 如果admin
grants SELECT
globally to u1
and u2
, the result differs for each user:admin
对u1
和u2
全局授予SELECT
,则每个用户的结果都不同:
If 如果admin
grants SELECT
globally to u1
, who has no SELECT
privilege to begin with, u1
inherits the admin
privilege restriction:admin
对u1
全局授予SELECT
权限,而u1
一开始就没有SELECT
权限,则u1
将继承管理员权限限制:
mysql>GRANT SELECT ON *.* TO u1;
mysql>SHOW GRANTS FOR u1;
+------------------------------------------+ | Grants for u1@% | +------------------------------------------+ | GRANT SELECT ON *.* TO `u1`@`%` | | REVOKE SELECT ON `mysql`.* FROM `u1`@`%` | +------------------------------------------+
On the other hand, 另一方面,u2
already holds a global SELECT
privilege without restriction. u2
已经不受限制地拥有全局SELECT
特权。GRANT
can only add to a grantee's existing privileges, not reduce them, so if admin
grants SELECT
globally to u2
, u2
does not inherit the admin
restriction:GRANT
只能增加被授予者的现有权限,而不能减少它们,因此如果admin
对u2
全局授予SELECT
权限,u2
不会继承admin
限制:
mysql>GRANT SELECT ON *.* TO u2;
mysql>SHOW GRANTS FOR u2;
+---------------------------------+ | Grants for u2@% | +---------------------------------+ | GRANT SELECT ON *.* TO `u2`@`%` | +---------------------------------+
If a 如果GRANT
statement includes an AS
clause, the privilege restrictions applied are those on the user/role combination specified by the clause, rather than those on the user who executes the statement. user
GRANT
语句包含AS user
子句,则应用的特权限制是对该子句指定的用户/角色组合的特权限制,而不是对执行该语句的用户的特权限制。For information about the 有关AS
clause, see Section 13.7.1.6, “GRANT Statement”.AS
子句的信息,请参阅第13.7.1.6节,“GRANT语句”。
Restrictions on new privileges granted to an account are added to any existing restrictions for that account:对授予帐户的新特权的限制将添加到该帐户的任何现有限制中:
mysql>CREATE USER u1;
mysql>GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
mysql>REVOKE INSERT ON mysql.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+---------------------------------------------------------+ | Grants for u1@% | +---------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` | | REVOKE INSERT ON `mysql`.* FROM `u1`@`%` | +---------------------------------------------------------+ mysql>REVOKE DELETE, UPDATE ON db2.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+---------------------------------------------------------+ | Grants for u1@% | +---------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` | | REVOKE UPDATE, DELETE ON `db2`.* FROM `u1`@`%` | | REVOKE INSERT ON `mysql`.* FROM `u1`@`%` | +---------------------------------------------------------+
Aggregation of privilege restrictions applies both when privileges are partially revoked explicitly (as just shown) and when restrictions are inherited implicitly from the user who executes the statement or the user mentioned in an 特权限制的聚合既适用于部分明确撤销特权的情况(如刚刚所示),也适用于从执行语句的用户或AS
clause.user
AS user
子句中提到的用户隐式继承限制的情况。
If an account has a privilege restriction on a schema:如果帐户对架构有特权限制:
The account cannot grant to other accounts a privilege on the restricted schema or any object within it.该帐户无法向其他帐户授予受限架构或其中任何对象的权限。
Another account that does not have the restriction can grant privileges to the restricted account for the restricted schema or objects within it. Suppose that an unrestricted user executes these statements:另一个没有限制的帐户可以为受限制的帐户授予权限,以访问其中的受限制架构或对象。假设一个不受限制的用户执行以下语句:
CREATE USER u1; GRANT SELECT, INSERT, UPDATE ON *.* TO u1; REVOKE SELECT, INSERT, UPDATE ON mysql.* FROM u1; GRANT SELECT ON mysql.user TO u1; -- grant table privilege GRANT SELECT(Host,User) ON mysql.db TO u1; -- grant column privileges
The resulting account has these privileges, with the ability to perform limited operations within the restricted schema:生成的帐户具有以下特权,能够在受限架构内执行有限的操作:
mysql> SHOW GRANTS FOR u1;
+-----------------------------------------------------------+
| Grants for u1@% |
+-----------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE ON *.* TO `u1`@`%` |
| REVOKE SELECT, INSERT, UPDATE ON `mysql`.* FROM `u1`@`%` |
| GRANT SELECT (`Host`, `User`) ON `mysql`.`db` TO `u1`@`%` |
| GRANT SELECT ON `mysql`.`user` TO `u1`@`%` |
+-----------------------------------------------------------+
If an account has a restriction on a global privilege, the restriction is removed by any of these actions:如果帐户对全局权限有限制,则可以通过以下任何操作删除该限制:
Granting the privilege globally to the account by an account that has no restriction on the privilege.通过对权限没有限制的帐户全局授予该帐户权限。
Granting the privilege at the schema level.在架构级别授予特权。
Revoking the privilege globally.在全球范围内撤销特权。
Consider a user 考虑一个用户u1
who holds several privileges globally, but with restrictions on INSERT
, UPDATE
and DELETE
:u1
,他在全局拥有多个权限,但对INSERT
、UPDATE
和DELETE
有限制:
mysql>CREATE USER u1;
mysql>GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
mysql>REVOKE INSERT, UPDATE, DELETE ON mysql.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+----------------------------------------------------------+ | Grants for u1@% | +----------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` | | REVOKE INSERT, UPDATE, DELETE ON `mysql`.* FROM `u1`@`%` | +----------------------------------------------------------+
Granting a privilege globally to 从没有限制的帐户全局授予u1
from an account with no restriction removes the privilege restriction. For example, to remove the INSERT
restriction:u1
特权会删除特权限制。例如,要删除INSERT
限制:
mysql>GRANT INSERT ON *.* TO u1;
mysql>SHOW GRANTS FOR u1;
+---------------------------------------------------------+ | Grants for u1@% | +---------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` | | REVOKE UPDATE, DELETE ON `mysql`.* FROM `u1`@`%` | +---------------------------------------------------------+
Granting a privilege at the schema level to 在架构级别向u1
removes the privilege restriction. u1
授予特权会消除特权限制。For example, to remove the 例如,要删除UPDATE
restriction:UPDATE
限制:
mysql>GRANT UPDATE ON mysql.* TO u1;
mysql>SHOW GRANTS FOR u1;
+---------------------------------------------------------+ | Grants for u1@% | +---------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` | | REVOKE DELETE ON `mysql`.* FROM `u1`@`%` | +---------------------------------------------------------+
Revoking a global privilege removes the privilege, including any restrictions on it. 撤销全局特权会删除特权,包括对它的任何限制。For example, to remove the 例如,要删除DELETE
restriction (at the cost of removing all DELETE
access):DELETE
限制(以删除所有DELETE
访问为代价):
mysql>REVOKE DELETE ON *.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+-------------------------------------------------+ | Grants for u1@% | +-------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE ON *.* TO `u1`@`%` | +-------------------------------------------------+
If an account has a privilege at both the global and schema levels, you must revoke it at the schema level twice to effect a partial revoke. 如果一个帐户在全局和架构级别都有特权,则必须在架构级别撤销两次才能实现部分撤销。Suppose that 假设u1
has these privileges, where INSERT
is held both globally and on the world
schema:u1
具有这些特权,其中INSERT
在全局和world
模式上都有:
mysql>CREATE USER u1;
mysql>GRANT SELECT, INSERT ON *.* TO u1;
mysql>GRANT INSERT ON world.* TO u1;
mysql>SHOW GRANTS FOR u1;
+-----------------------------------------+ | Grants for u1@% | +-----------------------------------------+ | GRANT SELECT, INSERT ON *.* TO `u1`@`%` | | GRANT INSERT ON `world`.* TO `u1`@`%` | +-----------------------------------------+
Revoking 撤销INSERT
on world
revokes the schema-level privilege (SHOW GRANTS
no longer displays the schema-level GRANT
statement):world
上的INSERT
将撤销架构级权限(SHOW GRANTS
不再显示架构级GRANT
语句):
mysql>REVOKE INSERT ON world.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+-----------------------------------------+ | Grants for u1@% | +-----------------------------------------+ | GRANT SELECT, INSERT ON *.* TO `u1`@`%` | +-----------------------------------------+
Revoking 再次撤销INSERT
on world
again performs a partial revoke of the global privilege (SHOW GRANTS
now includes a schema-level REVOKE
statement):world
上的INSERT
会部分撤销全局权限(SHOW GRANTS
现在包含一个模式级REVOKE
语句):
mysql>REVOKE INSERT ON world.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+------------------------------------------+ | Grants for u1@% | +------------------------------------------+ | GRANT SELECT, INSERT ON *.* TO `u1`@`%` | | REVOKE INSERT ON `world`.* FROM `u1`@`%` | +------------------------------------------+
To provide access to accounts for some schemas but not others, partial revokes provide an alternative to the approach of explicitly granting schema-level access without granting global privileges. The two approaches have different advantages and disadvantages.为了为某些模式而不是其他模式提供对帐户的访问,部分撤销提供了一种替代方法,可以在不授予全局权限的情况下显式授予模式级访问权限。这两种方法各有优缺点。
Granting schema-level privileges and not global privileges:授予架构级别权限而非全局权限:
Adding a new schema: The schema is inaccessible to existing accounts by default. For any account to which the schema should be accessible, the DBA must grant schema-level access.添加新架构:默认情况下,现有帐户无法访问该架构。对于应该可以访问模式的任何帐户,DBA必须授予模式级访问权限。
Adding a new account: The DBA must grant schema-level access for each schema to which the account should have access.添加新帐户:DBA必须为帐户应该访问的每个模式授予模式级访问权限。
Granting global privileges in conjunction with partial revokes:授予全局权限并同时进行部分撤销:
Adding a new schema: The schema is accessible to existing accounts that have global privileges. For any such account to which the schema should be inaccessible, the DBA must add a partial revoke.添加新架构:具有全局权限的现有帐户可以访问该架构。对于模式不可访问的任何此类帐户,DBA必须添加部分撤销。
Adding a new account: The DBA must grant the global privileges, plus a partial revoke on each restricted schema.添加新帐户:DBA必须授予全局权限,并对每个受限制的模式进行部分撤销。
The approach that uses explicit schema-level grant is more convenient for accounts for which access is limited to a few schemas. The approach that uses partial revokes is more convenient for accounts with broad access to all schemas except a few.对于访问权限仅限于少数模式的帐户,使用显式模式级授权的方法更方便。使用部分撤销的方法对于可以广泛访问除少数模式之外的所有模式的帐户来说更方便。
Once enabled, 一旦启用,如果任何帐户有权限限制,则无法禁用partial_revokes
cannot be disabled if any account has privilege restrictions. partial_revokes
。If any such account exists, disabling 如果存在任何此类帐户,则禁用partial_revokes
fails:partial_revokes
失败:
For attempts to disable 对于在启动时禁用partial_revokes
at startup, the server logs an error message and enables partial_revokes
.partial_revokes
的尝试,服务器会记录一条错误消息并启用partial_revokes
。
For attempts to disable 对于在运行时尝试禁用partial_revokes
at runtime, an error occurs and the partial_revokes
value remains unchanged.partial_revokes
,会发生错误,partial_revokes
值保持不变。
To disable 要在存在限制时禁用partial_revokes
when restrictions exist, the restrictions first must be removed:partial_revokes
,必须首先删除限制:
Determine which accounts have partial revokes:确定哪些帐户有部分撤销:
SELECT User, Host, User_attributes->>'$.Restrictions' FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
For each such account, remove its privilege restrictions. Suppose that the previous step shows account 对于每个这样的帐户,删除其权限限制。假设上一步显示帐户u1
to have these restrictions:u1
具有以下限制:
[{"Database": "world", "Privileges": ["INSERT", "DELETE"]
Restriction removal can be done various ways:解除限制可以通过多种方式进行:
Grant the privileges globally, without restrictions:在全球范围内无限制地授予特权:
GRANT INSERT, DELETE ON *.* TO u1;
Grant the privileges at the schema level:在架构级别授予权限:
GRANT INSERT, DELETE ON world.* TO u1;
Revoke the privileges globally (assuming that they are no longer needed):全局撤销特权(假设不再需要):
REVOKE INSERT, DELETE ON *.* FROM u1;
Remove the account itself (assuming that it is no longer needed):删除帐户本身(假设不再需要):
DROP USER u1;
After all privilege restrictions are removed, it is possible to disable partial revokes:删除所有特权限制后,可以禁用部分撤销:
SET PERSIST partial_revokes = OFF;
In replication scenarios, if 在复制场景中,如果在任何主机上启用了partial_revokes
is enabled on any host, it must be enabled on all hosts. partial_revokes
,则必须在所有主机上启用它。Otherwise, 否则,用于部分撤销全局权限的REVOKE
statements to partially revoke a global privilege do not have the same effect for all hosts on which replication occurs, potentially resulting in replication inconsistencies or errors.REVOKE
语句对发生复制的所有主机没有相同的效果,可能会导致复制不一致或错误。