### 6.2.11 帐户类别

[](<>)[](<>)[](<>)[](<>)[](<>)

从 MySQL 8.0.16 开始，MySQL 结合了用户帐户类别的概念，基于[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权。

-   [系统和常规账户](account-categories.html#system-user-accounts)

-   [受系统影响的操作\_用户权限](account-categories.html#system-user-operations)

-   [系统和例会](account-categories.html#system-user-sessions)

-   [保护系统帐户免受常规帐户的操纵](account-categories.html#protecting-system-accounts)

#### 系统和常规账户

MySQL 引入了用户账户类别的概念，系统用户和普通用户根据是否拥有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权：

-   一个用户[`SYSTEM_USER`](privileges-provided.html#priv_system-user)权限是系统用户。

-   没有的用户[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权是普通用户。

    这[`SYSTEM_USER`](privileges-provided.html#priv_system-user)权限会影响给定用户可以应用其其他权限的帐户，以及该用户是否受到其他帐户的保护：

-   系统用户可以修改系统帐户和普通帐户。也就是说，拥有适当特权对常规帐户执行给定操作的用户可以通过拥有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)还可以对系统帐户执行操作。系统帐户只能由具有适当权限的系统用户修改，普通用户不能修改。

-   具有适当权限的普通用户可以修改普通帐户，但不能修改系统帐户。具有适当权限的系统用户和普通用户都可以修改普通帐户。

    如果用户具有对常规帐户执行给定操作的适当权限，[`SYSTEM_USER`](privileges-provided.html#priv_system-user)使用户还可以对系统帐户执行操作。[`SYSTEM_USER`](privileges-provided.html#priv_system-user)并不意味着任何其他特权，因此执行给定帐户操作的能力仍然取决于拥有任何其他必需的特权。例如，如果用户可以授予[`选择`](privileges-provided.html#priv_select)和[`更新`](privileges-provided.html#priv_update)普通帐户的特权，然后使用[`SYSTEM_USER`](privileges-provided.html#priv_system-user)用户还可以授予[`选择`](privileges-provided.html#priv_select)和[`更新`](privileges-provided.html#priv_update)到系统帐户。

    系统帐户和常规帐户之间的区别可以通过保护具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)来自没有权限的帐户的权限。例如，[`创建用户`](privileges-provided.html#priv_create-user)特权不仅可以创建新帐户，还可以修改和删除现有帐户。没有系统用户概念的用户[`创建用户`](privileges-provided.html#priv_create-user)权限可以修改或删除任何现有帐户，包括`根`帐户。系统用户的概念可以限制对`根`帐户（本身是系统帐户），因此只能由系统用户创建。普通用户[`创建用户`](privileges-provided.html#priv_create-user)权限仍然可以修改或删除现有帐户，但只能是普通帐户。

#### 受系统影响的操作\_用户权限

这[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权影响这些操作：

-   账户操纵。

    帐户操作包括创建和删除帐户、授予和撤销权限、更改帐户身份验证特征（例如凭据或身份验证插件）以及更改其他帐户特征（例如密码过期策略）。

    这[`SYSTEM_USER`](privileges-provided.html#priv_system-user)使用帐户管理语句来操作系统帐户需要特权，例如[`创建用户`](create-user.html)和[`授予`](grant.html).要防止帐户以这种方式修改系统帐户，请通过不授予其权限使其成为常规帐户[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权。（但是，为了完全保护系统帐户免受常规帐户的侵害，您还必须保留对系统帐户的修改权限`mysql`来自常规帐户的系统架构。看[保护系统帐户免受常规帐户的操纵](account-categories.html#protecting-system-accounts).)

-   杀死当前会话和在其中执行的语句。

    终止正在执行的会话或语句[`SYSTEM_USER`](privileges-provided.html#priv_system-user)权限，您自己的会话必须具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权，除了任何其他必需的特权（[`CONNECTION_ADMIN`](privileges-provided.html#priv_connection-admin)或已弃用的[`极好的`](privileges-provided.html#priv_super)特权）。

    在 MySQL 8.0.16 之前，[`CONNECTION_ADMIN`](privileges-provided.html#priv_connection-admin)特权（或已弃用的[`极好的`](privileges-provided.html#priv_super)privilege) 足以杀死任何会话或语句。

-   设置`定义者`存储对象的属性。

    设置`定义者`存储对象的属性到具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权，您必须拥有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权，除了任何其他必需的特权（[`SET_USER_ID`](privileges-provided.html#priv_set-user-id)或已弃用的[`极好的`](privileges-provided.html#priv_super)特权）。

    在 MySQL 8.0.16 之前，[`SET_USER_ID`](privileges-provided.html#priv_set-user-id)特权（或已弃用的[`极好的`](privileges-provided.html#priv_super)特权）足以指定任何`定义者`存储对象的值。

-   指定强制角色。

    一个角色具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权不能在值中列出[`强制角色`](server-system-variables.html#sysvar_mandatory_roles)系统变量。

    在 MySQL 8.0.16 之前，任何角色都可以列在[`强制角色`](server-system-variables.html#sysvar_mandatory_roles).

-   覆盖 MySQL Enterprise Audit 的审计日志过滤器中的“中止”项目。

    从 MySQL 8.0.28 开始，具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)权限被自动分配[`AUDIT_ABORT_EXEMPT`](privileges-provided.html#priv_audit-abort-exempt)特权，以便始终执行来自帐户的查询，即使审计日志过滤器中的“中止”项会阻止它们。帐户与[`SYSTEM_USER`](privileges-provided.html#priv_system-user)因此，特权可用于在审核错误配置后重新获得对系统的访问权限。看[第 6.4.5 节，“MySQL 企业审计”](audit-log.html).

#### 系统和例会

[](<>)[](<>)[](<>)

在服务器中执行的会话被区分为系统会话或常规会话，类似于系统用户和常规用户之间的区别：

-   一个会话拥有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)权限是一个系统会话。

-   一个不拥有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权是一个常规会话。

    常规会话只能执行允许常规用户执行的操作。系统会话还能够执行仅允许系统用户执行的操作。

    会话拥有的权限是直接授予其基础帐户的权限，以及授予会话中当前活动的所有角色的权限。因此，一个会话可能是一个系统会话，因为它的帐户已被授予[`SYSTEM_USER`](privileges-provided.html#priv_system-user)权限直接，或者因为会话激活了一个角色，该角色具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权。授予在会话中不活动的帐户的角色不会影响会话权限。

    因为激活和停用角色可以改变会话拥有的权限，所以会话可能会从常规会话更改为系统会话，反之亦然。如果会话激活或停用具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权，常规会话和系统会话之间的适当更改会立即发生，仅针对该会话：

-   如果一个常规会话激活一个角色[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权，会话成为系统会话。

-   如果系统会话使用[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权，会话变为常规会话，除非其他角色具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权仍然有效。

    这些操作对现有会话没有影响：

-   如果[`SYSTEM_USER`](privileges-provided.html#priv_system-user)特权被授予或撤销帐户，帐户的现有会话不会在常规会话和系统会话之间更改。授予或撤销操作仅影响帐户后续连接的会话。

-   由会话中调用的存储对象执行的语句以父会话的系统或常规状态执行，即使对象`定义者`属性命名系统帐户。

    由于角色激活仅影响会话而不影响帐户，因此授予具有[`SYSTEM_USER`](privileges-provided.html#priv_system-user)普通帐户的特权不会保护该帐户免受普通用户的侵害。该角色仅保护已激活该角色的帐户的会话，并仅保护该会话不被常规会话杀死。

#### 保护系统帐户免受常规帐户的操纵

帐户操作包括创建和删除帐户、授予和撤销权限、更改帐户身份验证特征（例如凭据或身份验证插件）以及更改其他帐户特征（例如密码过期策略）。

帐户操作可以通过两种方式完成：

-   通过使用帐户管理报表，例如[`创建用户`](create-user.html)和[`授予`](grant.html).这是首选方法。

-   通过使用语句直接修改授权表，例如[`插入`](insert.html)和[`更新`](update.html).不鼓励使用此方法，但对于在`mysql`包含授权表的系统架构。

    要完全保护系统帐户免受给定帐户的修改，请将其设为普通帐户，并且不要授予其修改权限`mysql`架构：

-   这[`SYSTEM_USER`](privileges-provided.html#priv_system-user)使用帐户管理语句操作系统帐户需要特权。要防止帐户以这种方式修改系统帐户，请通过不授予[`SYSTEM_USER`](privileges-provided.html#priv_system-user)给它。这包括不授予[`SYSTEM_USER`](privileges-provided.html#priv_system-user)授予该帐户的任何角色。

-   的特权`mysql`架构允许通过直接修改授权表来操作系统帐户，即使修改帐户是常规帐户。要限制普通帐户未经授权直接修改系统帐户，请不要授予系统帐户的修改权限`mysql`帐户的架构（或授予该帐户的任何角色）。如果常规帐户必须具有适用于所有模式的全局权限，`mysql`使用部分撤销施加的权限限制可以防止模式修改。看[第 6.2.12 节，“使用部分撤销的权限限制”](partial-revokes.html).

笔记

与扣留不同[`SYSTEM_USER`](privileges-provided.html#priv_system-user)权限，防止账户修改系统账户而非普通账户，代扣代缴`mysql`架构特权可防止帐户修改系统帐户以及常规帐户。这应该不是问题，因为如前所述，不鼓励直接修改授权表。

假设您要创建一个用户`u1`谁拥有所有模式的所有特权，除了`u1`应该是没有能力修改系统帐户的普通用户。假设[`部分撤销`](server-system-variables.html#sysvar_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`架构访问，例如只读访问。以下示例创建一个具有`选择`,`插入`,`更新`， 和`删除`所有模式的全局权限，但仅限`选择`为了`mysql`架构：

```
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`.以下语句启用只读访问`u1`内`mysql`架构，但仅适用于`D b`表和`主持人`和`用户`的列`用户`桌子：

```
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;
```
