8.2.11 账户类别
从 MySQL 8.0.16 开始,MySQL 引入了基于 SYSTEM_USER
权限的用户账户类别概念。
- 系统和常规账户
- SYSTEM_USER 权限影响的操作
- 系统和常规会话
- 保护系统账户免受常规账户篡改
系统和常规账户
MySQL 引入了用户账户类别的概念,根据是否拥有 SYSTEM_USER
权限来区分系统用户和常规用户:
- 拥有
SYSTEM_USER
权限的用户是系统用户。 - 没有
SYSTEM_USER
权限的用户是常规用户。
SYSTEM_USER
权限对用户可以应用其它权限的账户产生影响,以及用户是否受到其他账户的保护:
- 系统用户可以修改系统和常规账户。也就是说,拥有适当权限在常规账户上执行特定操作的用户,通过拥有
SYSTEM_USER
权限也能在系统账户上执行该操作。系统账户只能被拥有适当权限的系统用户修改,而不能被常规用户修改。 - 拥有适当权限的常规用户可以修改常规账户,但不能修改系统账户。系统账户可以被拥有适当权限的系统用户和常规用户修改。
如果用户有适当权限在常规账户上执行特定操作,SYSTEM_USER
使用户也能在系统账户上执行该操作。SYSTEM_USER
不意味着任何其他权限,因此执行特定账户操作的能力仍取决于是否拥有任何其他所需权限。例如,如果用户可以授予常规账户 SELECT
和 UPDATE
权限,那么拥有 SYSTEM_USER
的用户也可以授予系统账户 SELECT
和 UPDATE
权限。
系统账户和普通账户之间的区别通过保护具有SYSTEM_USER
特权的账户免受没有该特权的账户的影响,从而更好地控制某些账户管理问题。例如,CREATE USER
特权不仅允许创建新账户,还允许修改和删除现有账户。没有系统用户概念,拥有CREATE USER
特权的用户可以修改或删除任何现有账户,包括root
账户。系统用户概念使得限制对root
账户(本身是系统账户)的修改只能由系统用户进行。拥有CREATE USER
特权的普通用户仍然可以修改或删除现有账户,但只能是普通账户。
受SYSTEM_USER
特权影响的操作
SYSTEM_USER
特权影响以下操作:
- 账户操作。
账户操作包括创建和删除账户,授予和撤销特权,更改账户认证特性(如凭证或认证插件),以及更改其他账户特性,如密码过期策略。
使用账户管理语句(如CREATE USER
和GRANT
")操纵系统账户需要SYSTEM_USER
特权。为防止账户以这种方式修改系统账户,将其设为普通账户,不授予SYSTEM_USER
特权。(然而,要完全保护系统账户免受普通账户的修改,还必须对普通账户限制对mysql
系统模式的修改特权。请参见保护系统账户免受普通账户操纵。) - 终止当前会话和其中执行的语句。
要终止使用SYSTEM_USER
特权执行的会话或语句,您自己的会话必须具有SYSTEM_USER
特权,以及任何其他所需特权(CONNECTION_ADMIN
或已弃用的SUPER
特权)。
从 MySQL 8.0.30 开始,如果将服务器置于脱机模式的用户没有SYSTEM_USER
权限,则具有SYSTEM_USER
权限的连接客户端用户也不会被断开连接。但是,这些用户在服务器处于脱机模式时无法启动新连接,除非他们还具有CONNECTION_ADMIN
或SUPER
权限。仅仅是他们现有的连接不会被终止,因为需要SYSTEM_USER
权限才能执行该操作。
在 MySQL 8.0.16 之前,CONNECTION_ADMIN
权限(或已弃用的SUPER
权限)足以终止任何会话或语句。 - 为存储对象设置
DEFINER
属性。
要将存储对象的DEFINER
属性设置为具有SYSTEM_USER
权限的帐户,您必须具有SYSTEM_USER
权限,以及任何其他所需权限(SET_USER_ID
或已弃用的SUPER
权限)。
在 MySQL 8.0.16 之前,SET_USER_ID
权限(或已弃用的SUPER
权限)足以为存储对象指定任何DEFINER
值。 - 指定强制角色。
具有SYSTEM_USER
权限的角色不能在mandatory_roles
系统变量的值中列出。
在 MySQL 8.0.16 之前,任何角色都可以列在mandatory_roles
中。 - 覆盖 MySQL Enterprise Audit 的审计日志过滤器中的“中止”项目。
从 MySQL 8.0.28 开始,具有SYSTEM_USER
权限的帐户会自动被分配AUDIT_ABORT_EXEMPT
权限,因此即使审计日志过滤器中的“中止”项目会阻止它们,该帐户的查询也会始终执行。具有SYSTEM_USER
权限的帐户因此可用于在审计配置错误后恢复对系统的访问。参见第 8.4.5 节,“MySQL Enterprise Audit”。
系统和常规会话
在服务器内执行的会��被区分为系统会话或常规会话,类似于系统和常规用户之间的区别:
- 拥有
SYSTEM_USER
权限的会话是系统会话。 - 不具有
SYSTEM_USER
权限的会话是普通会话。
普通会话只能执行普通用户允许的操作。系统会话还能执行仅允许系统用户的操作。
会话拥有的权限包括直接授予其基础帐户的权限,以及授予会话内所有当前活动角色的权限。因此,会话可能是系统会话,因为其帐户直接被授予SYSTEM_USER
权限,或者因为会话已激活具有SYSTEM_USER
权限的角色。授予帐户但在会话中未激活的角色不会影响会话权限。
因为激活和停用角色可以改变会话拥有的权限,会话可能从普通会话变为系统会话,反之亦然。如果会话激活或停用具有SYSTEM_USER
权限的角色,则会话之间的普通和系统会话之间的适当变化立即发生,仅适用于该会话:
- 如果普通会话激活具有
SYSTEM_USER
权限的角色,则该会话将变为系统会话。 - 如果系统会话停用具有
SYSTEM_USER
权限的角色,则该会话将变为普通会话,除非仍有其他具有SYSTEM_USER
权限的角色处于活动状态。
这些操作不会影响现有会话:
- 如果向帐户授予或撤销
SYSTEM_USER
权限,则帐户的现有会话在普通会话和系统会话之间不会发生变化。授予或撤销操作仅影响帐户后续连接的会话。 - 在会话中调用的存储对象执行的语句将以父会话的系统或普通状态执行,即使对象的
DEFINER
属性命名了系统帐户。
因为角色激活仅影响会话而不影响帐户,向普通帐户授予具有SYSTEM_USER
权限的角色不会保护该帐户免受普通用户的攻击。该角色仅保护已激活该角色的帐户的会话,并仅保护会话免受普通会话的终止。
保护系统帐户免受普通帐户的操纵
帐户操作包括创建和删除帐户,授予和撤销权限,更改帐户身份验证特性,如凭据或身份验证插件,以及更改其他帐户特性,如密码过期策略。
帐户操作可以通过两种方式完成:
- 通过使用诸如
CREATE USER
和GRANT
等帐户管理语句。这是首选方法。 - 通过使用诸如
INSERT
和UPDATE
等语句直接修改授权表。虽然不鼓励这种方法,但对于具有mysql
系统模式上适当特权的用户是可能的。
要完全保护系统帐户免受特定帐户的修改,将其设置为常规帐户,并不授予mysql
模式的修改特权:
- 使用帐户管理语句操作系统帐户需要
SYSTEM_USER
特权。为防止帐户以这种方式修改系统帐户,将其设置为常规帐户,不授予SYSTEM_USER
。这包括不授予任何角色授予的帐户SYSTEM_USER
。 mysql
模式的特权允许通过直接修改授权表来操作系统帐户,即使修改帐户是常规帐户。为了防止常规帐户通过直接修改未经授权地修改系统帐户,请不要向帐户(或任何授予帐户的角色)授予mysql
模式的修改特权。如果常规帐户必须具有适用于所有模式的全局特权,则可以使用部分撤销施加的特权限制来阻止mysql
模式的修改。参见 Section 8.2.12, “Privilege Restriction Using Partial Revokes”。
注意
与不授予SYSTEM_USER
特权不同,阻止帐户修改系统帐户但不是常规帐户,不授予mysql
模式特权会阻止帐户修改系统帐户以及常规帐户。这不应该是一个问题,因为如前所述,不鼓励直接修改授权表。
假设您想要创建一个名为u1
的用户,该用户对所有模式具有所有特权,但u1
应该是一个不能修改系统帐户的常规用户。假设partial_revokes
系统变量已启用,配置u1
如下:
CREATE USER u1 IDENTIFIED BY '*password*'; GRANT ALL ON *.* TO u1 WITH GRANT OPTION; -- GRANT ALL includes SYSTEM_USER, so at this point -- u1 can manipulate system or regular accounts REVOKE SYSTEM_USER ON *.* FROM u1; -- Revoking SYSTEM_USER makes u1 a regular user; -- now u1 can use account-management statements -- to manipulate only regular accounts REVOKE ALL ON mysql.* FROM u1; -- This partial revoke prevents u1 from directly -- modifying grant tables to manipulate accounts
为防止帐户访问所有mysql
系统模式,撤销其在mysql
模式上的所有特权,如上所示。也可以允许部分mysql
模式访问,例如只读访问。以下示例创建一个帐户,该帐户对所有模式具有全局的SELECT
、INSERT
、UPDATE
和DELETE
特权,但对mysql
模式仅具有SELECT
特权:
CREATE USER u2 IDENTIFIED BY '*password*'; GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u2; REVOKE INSERT, UPDATE, DELETE ON mysql.* FROM u2;
另一种可能性是撤销所有mysql
模式的权限,但授予对特定mysql
表或列的访问权限。即使对mysql
进行部分撤销,也可以完成此操作。以下语句允许在mysql
模式内对u1
进行只读访问,但仅限于db
表以及user
表的Host
和User
列:
CREATE USER u3 IDENTIFIED BY '*password*'; GRANT ALL ON *.* TO u3; REVOKE ALL ON mysql.* FROM u3; GRANT SELECT ON mysql.db TO u3; GRANT SELECT(Host,User) ON mysql.user TO u3;
8.2.12 使用部分撤销进行权限限制
在 MySQL 8.0.16 之前,不可能授予全局适用的权限,除了某些模式。从 MySQL 8.0.16 开始,如果启用了partial_revokes
系统变量,则可以实现。具体来说,对于在全局级别具有权限的用户,partial_revokes
使得可以撤销特定模式的权限,同时保留其他模式的权限。因此,施加的权限限制可能对具有全局权限但不应被允许访问某些模式的账户的管理很有用。例如,可以允许一个账户修改任何表,除了mysql
系统模式中的表。
- 使用部分撤销
- 部分撤销与显式模式授权
- 禁用部分撤销
- 部分撤销和复制
注意
为简洁起见,此处显示的CREATE USER
语句不包括密码。在生产环境中,请始终分配账户密码。
使用部分撤销
partial_revokes
系统变量控制是否可以对账户施加权限限制。默认情况下,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 '%'
要允许REVOKE
操作,请启用partial_revokes
:
SET PERSIST partial_revokes = ON;
SET PERSIST
为运行中的 MySQL 实例设置一个值。它还保存该值,使其在后续服务器重启时保留。要更改运行中的 MySQL 实例的值,而不使其在后续重启时保留,使用GLOBAL
关键字而不是PERSIST
。参见 Section 15.7.6.1, “SET Syntax for Variable Assignment”。
启用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
在其输出中将部分撤销列为REVOKE
语句。结果表明u1
具有全局SELECT
和INSERT
权限,只是INSERT
无法用于world
模式中的表。也就是说,u1
对world
表的访问是只读的。
服务器记录通过部分撤销在mysql.user
系统表中实施的权限限制。如果一个账户有部分撤销,其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"]}] | +------+------+------------------------------------------------------+
注意
尽管可以对任何模式施加部分撤销,但对mysql
系统模式的权限限制特别有用,作为防止常规账户修改系统账户的策略的一部分。请参阅防止常规账户操纵系统账户。
部分撤销操作受到以下条件的约束:
- 可以使用部分撤销对不存在的模式施加限制,但只有在撤销的权限是全局授予的情况下才可以。如果权限没有全局授予,为不存在的模式撤销它会产生错误。
- 部分撤销仅适用于模式级。您不能对仅全局适用的权限(如
FILE
或BINLOG_ADMIN
)或表、列或例程权限使用部分撤销。 - 在权限分配中,启用
partial_revokes
会导致 MySQL 将模式名称中未转义的_
和%
SQL 通配符字符解释为文字字符,就好像它们已经被转义为\_
和\%
一样。因为这会改变 MySQL 解释权限的方式,建议在启用partial_revokes
的安装中避免未转义的通配符字符在权限分配中出现。
如前所述,模式级权限的部分撤销在SHOW GRANTS
输出中显示为REVOKE
语句。这与SHOW GRANTS
表示“普通”模式级权限的方式不同:
- 当授予时,模式级权限通过其自己的
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`@`%` | +---------------------------------------+
- 当撤销时,模式级权限会简单地从输出中消失。它们不会显示为
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`@`%` | +--------------------------------+
当用户授予特权时,授予者对特权的任何限制都会被受让者继承,除非受让者已经拥有该特权而没有限制。考虑以下两个用户,其中一个拥有全局SELECT
特权:
CREATE USER u1, u2; GRANT SELECT ON *.* TO u2;
假设一个管理用户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`@`%` | +------------------------------------------------------+
如果admin
全局授予u1
和u2``SELECT
,则每个用户的结果不同:
- 如果
admin
全局授予u1``SELECT
,而u1
一开始没有SELECT
特权,u1
会继承admin
的特权限制:
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`@`%` | +------------------------------------------+
- 另一方面,
u2
已经拥有全局SELECT
特权而没有限制。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`@`%` | +---------------------------------+
如果GRANT
语句包括一个AS *
user*
子句,应用的特权限制是子句指定的用户/角色组合上的,而不是执行该语句的用户上的。有关AS
子句的信息,请参见 Section 15.7.1.6, “GRANT Statement”。
授予给账户的新特权的限制将添加到该账户的任何现有限制中:
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*
子句中提到的用户隐式继承限制时。
如果账户在模式上有特权限制:
- 该账户无法向其他账户授予对受限模式或其中任何对象的特权。
- 另一个没有限制的账户可以向受限账户授予受限模式或其中对象的特权。假设一个无限制用户执行以下语句:
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
- 结果账户具有这些特权,能够在受限模式内执行有限操作:
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`@`%` | +-----------------------------------------------------------+
如果账户对全局特权有限制,这些操作中的任何一个都会移除限制:
- 由没有对特权限制的账户全局授予账户特权。
- 在模式级别授予特权。
- 全局撤销特权。
考虑一个全局拥有多个特权但对INSERT
、UPDATE
和DELETE
有限制的用户u1
:
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
限制:
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
限制:
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
访问权限为代价):
mysql> REVOKE DELETE ON *.* FROM u1; mysql> SHOW GRANTS FOR u1; +-------------------------------------------------+ | Grants for u1@% | +-------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE ON *.* TO `u1`@`%` | +-------------------------------------------------+
如果一个帐户在全局和模式级别都有权限,则必须在模式级别撤销两次才能实现部分撤销。假设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`@`%` | +-----------------------------------------+
撤销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`@`%` | +-----------------------------------------+
再次撤销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`@`%` | +------------------------------------------+
部分撤销与明确的模式授予
为某些模式提供帐户访问权限,但不提供其他模式的访问权限,部分撤销提供了一种替代方法,可以在不授予全局特权的情况下明确授予模式级别的访问权限。这两种方法各有优缺点。
授予模式级别特权而不是全局特权:
- 添加新模式:默认情况下,现有帐户无法访问该模式。对于任何应该访问该模式的帐户,DBA 必须授予模式级别的访问权限。
- 添加新帐户:DBA 必须为每个应该访问的模式授予模式级别的访问权限。
在与部分撤销一起授予全局特权:
- 添加新模式:对于具有全局特权的现有帐户,可以访问该模式。对于任何应该无法访问该模式的帐户,DBA 必须添加部分撤销。
- 添加新帐户:DBA 必须授予全局特权,以及对每个受限制的模式进行部分撤销。
使用明确的模式级别授予方法更方便,适用于访问仅限于少数模式的帐户。使用部分撤销的方法更适用于对所有模式具有广泛访问权限的帐户,除了少数模式。
禁用部分撤销
一旦启用,partial_revokes
如果任何帐户具有特权限制,则无法禁用。如果存在这样的帐户,则禁用 partial_revokes
将失败:
- 尝试在启动时禁用
partial_revokes
时,服务器会记录错误消息并启用partial_revokes
。 - 尝试在运行时禁用
partial_revokes
时,会发生错误,并且partial_revokes
的值保持不变。
要在存在限制时禁用 partial_revokes
,必须首先移除限制:
- 确定哪些帐户具有部分撤销:
SELECT User, Host, User_attributes->>'$.Restrictions' FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
- 对于每个这样的帐户,删除其特权限制。假设前一步显示帐户
u1
具有这些限制:
[{"Database": "world", "Privileges": ["INSERT", "DELETE"]
- 可以通过多种方式进行限制移除:
- 全局授予权限,无限制:
GRANT INSERT, DELETE ON *.* TO u1;
- 在模式级别授予权限:
GRANT INSERT, DELETE ON world.* TO u1;
- 全局撤销特权(假设不再需要):
REVOKE INSERT, DELETE ON *.* FROM u1;
- 删除帐户本身(假设不再需要):
DROP USER u1;
删除所有特权限制后,可以禁用部分撤销:
SET PERSIST partial_revokes = OFF;
部分撤销和复制
在复制场景中,如果任何主机上启用了 partial_revokes
,则所有主机上都必须启用。否则,对于在复制发生的所有主机上部分撤销全局特权的 REVOKE
语句可能不会对所有主机产生相同的效果,可能导致复制不一致或错误。
当启用 partial_revokes
时,GRANT
语句的二进制日志中记录了扩展语法,包括发出该语句的当前用户及其当前活动角色。如果以这种方式记录的用户或角色在副本上不存在,则复制应用程序线程会在带有错误的 GRANT
语句处停止。确保在复制源服务器上发出或可能发出 GRANT
语句的所有用户帐户也存在于副本上,并且具有与源服务器上相同的角色集。
8.2.13 权限更改何时生效
如果mysqld服务器在没有--skip-grant-tables
选项的情况下启动,它在启动序列期间将所有授权表内容读入内存。在那一点上,内存中的表对访问控制生效。
如果您间接修改授权表,使用帐户管理语句,服务器会立即注意到这些更改并重新加载授权表到内存中。帐户管理语句在第 15.7.1 节“帐户管理语句”中描述。例如包括GRANT
、REVOKE
、SET PASSWORD
和RENAME USER
。
如果您直接修改授权表,使用诸如INSERT
、UPDATE
或DELETE
等语句(不建议这样做),则在告知服务器重新加载表或重新启动之前,更改不会影响权限检查。因此,如果您直接更改授权表但忘记重新加载它们,更改将不会生效,直到重新启动服务器。这可能会让您想知道为什么您的更改似乎没有任何影响!
要告知服务器重新加载授权表,请执行刷新权限操作。这可以通过发出FLUSH PRIVILEGES
语句或执行mysqladmin flush-privileges或mysqladmin reload命令来完成。
重新加载授权表会影响每个现有客户端会话的权限:
- 表和列权限更改将在客户端的下一个请求中生效。
- 数据库权限更改将在客户端执行
USE *
db_name*
语句的下一次生效。
注意
客户端应用程序可能会缓存数据库名称;因此,这种效果可能对它们不可见,除非实际更改为不同的数据库。 - 静态全局权限和密码对已连接的客户端不受影响。这些更改仅在后续连接的会话中生效。动态全局权限的更改立即生效。有关静态和动态权限之间的区别,请参阅静态与动态权限。
会话中活动角色集的更改立即生效,仅对该会话有效。SET ROLE
语句执行会话角色的激活和停用(参见第 15.7.1.11 节,“SET ROLE Statement”)。
如果服务器使用--skip-grant-tables
选项启动,则不会读取授权表或实施任何访问控制。任何用户都可以连接并执行任何操作,这是不安全的。要使这样启动的服务器读取表并启用访问检查,请刷新权限。
MySQL8 中文参考(二十五)(2)https://developer.aliyun.com/article/1566165