如果启用了partial_revokes 系统变量,就可以授予全局适用的权限。具体来说,对于拥有全局级别权限的用户,partial_revokes 允许撤销特定模式的权限,同时保留其他模式的权限。因此施加的权限限制对于管理拥有全局权限但不应被允许访问某些模式的帐户可能非常有用。例如,可以允许一个帐户修改任何表,但不包括 mysql 系统模式中的表。It is possible to grant privileges that apply globally if the
partial_revokes system variable
is enabled. 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. 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.
为了简洁起见,这里显示的 CREATE USER 语句未包含密码。在生产环境中,请始终为账户分配密码。For brevity, CREATE USER
statements shown here do not include passwords. For production
use, always assign account passwords.
partial_revokes 系统变量控制是否可以对帐户设置权限限制。默认情况下,partial_revokes 是禁用的,尝试部分撤销全局权限会产生错误:The partial_revokes system
variable controls whether privilege restrictions can be placed
on accounts. By default,
partial_revokes is disabled and
attempts to partially revoke global privileges produce an error:
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 '%'
要允许 REVOKE 操作,请启用 partial_revokes:To permit the REVOKE operation,
enable partial_revokes:
SET PERSIST partial_revokes = ON;
SET
PERSIST 为正在运行的 MySQL 实例设置一个值。它还会保存该值,使其在随后的服务器重启中保留。要更改正在运行的 MySQL 实例的值而不让其在随后的重启中保留,请使用 GLOBAL 关键字而不是 PERSIST。参见 第 15.7.6.1 节,“SET 变量赋值语法”。SET
PERSIST sets a value for the running MySQL instance.
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 GLOBAL keyword rather than
PERSIST. See Section 15.7.6.1, “SET Syntax for Variable Assignment”.
启用 partial_revokes 后,部分撤销将成功:With partial_revokes enabled,
the partial revoke succeeds:
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 会在其输出中将部分撤销列为 REVOKE 语句。结果显示 u1 拥有全局 SELECT 和 INSERT 权限,但 INSERT 无法在 world 模式的表上使用。也就是说,u1 对 world 表的访问仅限于读取。SHOW GRANTS lists partial revokes
as REVOKE statements in its
output. The result indicates that u1 has
global SELECT and
INSERT privileges, except that
INSERT cannot be exercised for
tables in the world schema. That is, access
by u1 to world tables is
read only.
服务器通过在 mysql.user 系统表中实施部分撤销来记录权限限制。如果一个账户有部分撤销,其 User_attributes 列的值会有一个 Restrictions 属性:The server records privilege restrictions implemented through
partial revokes in the mysql.user system
table. If an account has partial revokes, its
User_attributes column value has a
Restrictions attribute:
mysql>SELECT User, Host, User_attributes->>'$.Restrictions'FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';+------+------+------------------------------------------------------+ | User | Host | User_attributes->>'$.Restrictions' | +------+------+------------------------------------------------------+ | u1 | % | [{"Database": "world", "Privileges": ["INSERT"]}] | +------+------+------------------------------------------------------+
虽然可以对任何模式施加部分撤销,但特别是在 mysql 系统模式上实施的权限限制在防止普通账户修改系统账户的策略中非常有用。请参见 防止普通账户操作系统账户。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.
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.
部分撤销仅适用于模式级别。对于仅全局适用的权限(例如
FILE或BINLOG_ADMIN),或者表、列或例程权限,不能使用部分撤销。Partial revokes apply at the schema level only. You cannot use partial revokes for privileges that apply only globally (such asFILEorBINLOG_ADMIN), or for table, column, or routine privileges.在权限分配中,启用
partial_revokes会导致 MySQL 将模式名称中未转义的_和%SQL 通配符字符解释为字面字符,就像它们已经被转义为\_和\%一样。由于这会改变 MySQL 对权限的解释,因此在可能启用partial_revokes的安装环境中,建议在权限分配中避免使用未转义的通配符字符。In privilege assignments, enablingpartial_revokescauses 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\%. Because this changes how MySQL interprets privileges, it may be advisable to avoid unescaped wildcard characters in privilege assignments for installations wherepartial_revokesmay be enabled.
如前所述,模式级权限的部分撤销会在 SHOW GRANTS 输出中显示为 REVOKE 语句。这与 SHOW GRANTS 表示“普通”模式级权限的方式有所不同:As mentioned previously, partial revokes of schema-level
privileges appear in SHOW GRANTS
output as REVOKE statements. This
differs from how SHOW GRANTS
represents “plain” schema-level privileges:
当被授予时,模式级权限会在输出中由它们自身的
GRANT语句表示:When granted, schema-level privileges are represented by their ownGRANTstatements in the output: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`@`%` | +---------------------------------------+当撤销时,模式级别的权限会直接从输出中消失。它们不会以
REVOKE语句的形式出现:When revoked, schema-level privileges simply disappear from the output. They do not appear asREVOKEstatements: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`@`%` | +--------------------------------+
当用户授予权限时,授予者在该权限上的任何限制都会被受权者继承,除非受权者已经拥有该权限且没有限制。考虑以下两个用户,其中一个拥有全局 SELECT 权限: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:
CREATE USER u1, u2; GRANT SELECT ON *.* TO u2;
假设一个管理用户 admin 拥有一个全局但部分被撤销的 SELECT 权限:Suppose that an administrative user admin has
a global but partially revoked
SELECT privilege:
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`@`%` | +------------------------------------------------------+
如果 admin 全局授予 SELECT 给 u1 和 u2,每个用户的结果会有所不同:If admin grants
SELECT globally to
u1 and u2, the result
differs for each user:
If
admin授予SELECTglobally tou1, who has noSELECTprivilege to begin with,u1inherits theadminprivilege restriction:IfadmingrantsSELECTglobally tou1, who has noSELECTprivilege to begin with,u1inherits theadminprivilege restriction: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,
u2already holds a globalSELECTprivilege without restriction.GRANTcan only add to a grantee's existing privileges, not reduce them, so ifadmin授予SELECTglobally tou2,u2does not inherit theadminrestriction:On the other hand,u2already holds a globalSELECTprivilege without restriction.GRANTcan only add to a grantee's existing privileges, not reduce them, so ifadmingrantsSELECTglobally tou2,u2does not inherit theadminrestriction:mysql>
GRANT SELECT ON *.* TO u2;mysql>SHOW GRANTS FOR u2;+---------------------------------+ | Grants for u2@% | +---------------------------------+ | GRANT SELECT ON *.* TO `u2`@`%` | +---------------------------------+
如果 GRANT 语句包含 AS 子句,则应用的权限限制是该子句指定的用户/角色组合的权限限制,而不是执行该语句的用户的权限限制。有关 userAS 子句的详细信息,请参阅 第 15.7.1.6 节,“GRANT 语句”。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. For information about the
userAS clause, see Section 15.7.1.6, “GRANT Statement”.
对账户授予的新权限的限制将被添加到该账户现有的限制中: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`@`%` | +---------------------------------------------------------+
特权限制的聚合适用于在特权被部分明确撤销时(如刚才所示),以及当限制从执行语句的用户或在 AS
user 子句中提到的用户隐式继承时。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
如果一个账户在某个模式上有权限限制: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.
考虑一个用户 u1,他在全局拥有多个权限,但在 INSERT、UPDATE 和 DELETE 上有一些限制:Consider a user u1 who holds several
privileges globally, but with restrictions on
INSERT,
UPDATE and
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`@`%` | +----------------------------------------------------------+
从没有限制的账户全局授予权限给 u1 会移除权限限制。例如,要移除 INSERT 限制:Granting a privilege globally to u1 from an
account with no restriction removes the privilege restriction.
For example, to remove the INSERT
restriction:
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`@`%` | +---------------------------------------------------------+
在模式级别授予权限给 u1 会移除权限限制。例如,要移除 UPDATE 限制:Granting a privilege at the schema level to
u1 removes the privilege restriction. For
example, to remove the UPDATE
restriction:
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`@`%` | +---------------------------------------------------------+
撤销全局权限会移除该权限,包括其上的任何限制。例如,要移除 DELETE 限制(但会移除所有 DELETE 访问权限):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):
mysql>REVOKE DELETE ON *.* FROM u1;mysql>SHOW GRANTS FOR u1;+-------------------------------------------------+ | Grants for u1@% | +-------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE ON *.* TO `u1`@`%` | +-------------------------------------------------+
如果一个账户在全局和模式级别都有某个权限,你必须在模式级别撤销两次才能实现部分撤销。假设 u1 拥有这些权限,其中 INSERT 权限在全局和 world 模式下都有: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:
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`@`%` | +-----------------------------------------+
撤销 INSERT 在 world 上,会撤销模式级别的权限(SHOW GRANTS 不再显示模式级别的 GRANT 语句):Revoking INSERT on
world revokes the schema-level privilege
(SHOW GRANTS no longer displays
the schema-level GRANT
statement):
mysql>REVOKE INSERT ON world.* FROM u1;mysql>SHOW GRANTS FOR u1;+-----------------------------------------+ | Grants for u1@% | +-----------------------------------------+ | GRANT SELECT, INSERT ON *.* TO `u1`@`%` | +-----------------------------------------+
再次撤销 INSERT 在 world 上,会对全局权限执行部分撤销(SHOW GRANTS 现在包括一个模式级别的 REVOKE 语句):Revoking INSERT on
world again performs a partial revoke of the
global privilege (SHOW GRANTS now
includes a schema-level REVOKE
statement):
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:
添加新模式:默认情况下,现有账户无法访问该模式。对于任何应当可以访问该模式的账户,DBA 必须授予模式级访问权限。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.
结合全局权限和部分撤销:Granting global privileges in conjunction with partial revokes:
添加新模式:具有全局权限的现有账户可以访问该模式。对于任何应当无法访问该模式的此类账户,DBA 必须添加部分撤销。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.
使用显式模式级授权的方法对于访问仅限于少数模式的账户更为方便。使用部分撤销权限的方法对于访问几乎所有模式但排除少数模式的账户更为方便。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.
一旦启用,partial_revokes 如果任何账户存在权限限制,则无法禁用。如果存在这样的账户,禁用 partial_revokes 将失败:Once enabled, partial_revokes
cannot be disabled if any account has privilege restrictions. If
any such account exists, disabling
partial_revokes fails:
在启动时尝试禁用
partial_revokes时,服务器会记录一条错误消息并启用partial_revokes。For attempts to disablepartial_revokesat startup, the server logs an error message and enablespartial_revokes.尝试在运行时禁用
partial_revokes时,会发生错误,并且partial_revokes的值保持不变。For attempts to disablepartial_revokesat runtime, an error occurs and thepartial_revokesvalue remains unchanged.
要在存在限制时禁用 partial_revokes,必须先移除这些限制:To disable partial_revokes when
restrictions exist, the restrictions first must be removed:
确定哪些账户有部分撤销:Determine which accounts have partial revokes:
SELECT User, Host, User_attributes->>'$.Restrictions' FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
对于每个这样的账户,移除其权限限制。假设上一步显示账户
u1具有这些限制:For each such account, remove its privilege restrictions. Suppose that the previous step shows accountu1to have these restrictions:[{"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;
在复制场景中,如果在任何主机上启用了partial_revokes,则必须在所有主机上启用。否则,用于部分撤销全局权限的REVOKE语句在所有进行复制的主机上不会产生相同的效果,可能导致复制不一致或错误。In replication scenarios, if
partial_revokes is enabled on
any host, it must be enabled on all hosts. 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.
当启用 partial_revokes 时,GRANT 语句的扩展语法会被记录在二进制日志中,包括发出该语句的当前用户及其当前活动角色。如果以这种方式记录的用户或角色在从服务器上不存在,复制应用线程将在该 GRANT 语句处停止并报错。请确保所有在复制源服务器上发出或可能发出 GRANT 语句的用户账户在从服务器上也存在,并且拥有与源服务器上相同的角色集合。When partial_revokes is
enabled, an extended syntax is recorded in the binary log for
GRANT statements, including the
current user that issued the statement and their currently
active roles. If a user or a role recorded in this way does not
exist on the replica, the replication applier thread stops at
the GRANT statement
with an error. Ensure that all user accounts that issue or might
issue GRANT statements on the
replication source server also exist on the replica, and have
the same set of roles as they have on the source.