### 6.2.21 设置帐户资源限制

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

限制客户端使用 MySQL 服务器资源的一种方法是设置全局[`max_user_connections`](server-system-variables.html#sysvar_max_user_connections)系统变量为非零值。这限制了任何给定帐户可以同时建立的连接数，但对客户端连接后可以执行的操作没有限制。此外，设置[`max_user_connections`](server-system-variables.html#sysvar_max_user_connections)无法管理个人帐户。MySQL 管理员对这两种类型的控制都很感兴趣。

为了解决这些问题，MySQL 允许对个人帐户使用这些服务器资源进行限制：

-   一个帐户每小时可以发出的查询数

-   一个帐户每小时可以发布的更新数量

-   一个账号每小时可以连接服务器的次数

-   一个帐户同时连接到服务器的数量

    客户端可以发出的任何语句都计入查询限制。只有修改数据库或表的语句才计入更新限制。

    此上下文中的“帐户”对应于`mysql.user`系统表。也就是说，根据`用户`和`主持人`中的值`用户`适用于连接的表行。例如，一个帐户`'usera'@'%.example.com'`对应于中的一行`用户`有的表`用户`和`主持人`的值`用户`和`%.example.com`， 以准许`用户`从任何主机连接`例子.com`领域。在这种情况下，服务器通过以下方式将这一行中的资源限制共同应用于所有连接`用户`从任何主机`例子.com`域，因为所有此类连接都使用相同的帐户。

    在 MySQL 5.0 之前，根据用户连接的实际主机评估“帐户”。可以通过启动服务器来选择这种较旧的记帐方法[`--old-style-user-limits`](server-options.html#option_mysqld_old-style-user-limits)选项。在这种情况下，如果`用户`同时从`host1.example.com`和`host2.example.com`，服务器将帐户资源限制分别应用于每个连接。如果`用户`从再次连接`host1.example.com`，服务器将该连接的限制与来自该主机的现有连接一起应用。

    要在帐户创建时为帐户建立资源限制，请使用[`创建用户`](create-user.html)陈述。要修改现有帐户的限制，请使用[`更改用户`](alter-user.html).提供一个`和`将每个资源命名为受限的子句。每个限制的默认值为零（无限制）。例如，要创建一个可以访问`顾客`数据库，但只能以有限的方式发出以下语句：


```
mysql> CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank'
    ->     WITH MAX_QUERIES_PER_HOUR 20
    ->          MAX_UPDATES_PER_HOUR 10
    ->          MAX_CONNECTIONS_PER_HOUR 5
    ->          MAX_USER_CONNECTIONS 2;
```

限制类型不必都在`和`子句，但那些被命名的可以以任何顺序出现。每个每小时限制的值应该是一个表示每小时计数的整数。为了`MAX_USER_CONNECTIONS`，限制是一个整数，表示帐户的最大同时连接数。如果此限制设置为零，则全局[`max_user_connections`](server-system-variables.html#sysvar_max_user_connections)系统变量值确定同时连接的数量。如果[`max_user_connections`](server-system-variables.html#sysvar_max_user_connections)也为零，帐户没有限制。

要修改现有帐户的限制，请使用[`更改用户`](alter-user.html)陈述。以下语句更改了查询限制`弗朗西斯`到 100：

```
mysql> ALTER USER 'francis'@'localhost' WITH MAX_QUERIES_PER_HOUR 100;
```

该语句仅修改指定的限制值，其他情况下保持帐户不变。

要删除限制，请将其值设置为零。例如，取消每小时多少次的限制`弗朗西斯`可以连接，使用这个语句：

```
mysql> ALTER USER 'francis'@'localhost' WITH MAX_CONNECTIONS_PER_HOUR 0;
```

如前所述，帐户的同时连接限制由`MAX_USER_CONNECTIONS`限制和[`max_user_connections`](server-system-variables.html#sysvar_max_user_connections)系统变量。假设全球[`max_user_connections`](server-system-variables.html#sysvar_max_user_connections)值为 10，三个帐户具有如下指定的单独资源限制：

```
ALTER USER 'user1'@'localhost' WITH MAX_USER_CONNECTIONS 0;
ALTER USER 'user2'@'localhost' WITH MAX_USER_CONNECTIONS 5;
ALTER USER 'user3'@'localhost' WITH MAX_USER_CONNECTIONS 20;
```

`用户1`连接限制为 10（全局[`max_user_connections`](server-system-variables.html#sysvar_max_user_connections)值），因为它有一个`MAX_USER_CONNECTIONS`零极限。`用户2`和`用户3`连接限制分别为 5 和 20，因为它们具有非零`MAX_USER_CONNECTIONS`限制。

服务器将帐户的资源限制存储在`用户`对应帐户的表行。这`最大问题`,`最大更新`， 和`最大连接数`列存储每小时限制，并且`max_user_connections`列存储`MAX_USER_CONNECTIONS`限制。（看[第 6.2.3 节，“授权表”](grant-tables.html).)

当任何帐户对其任何资源的使用设置了非零限制时，就会发生资源使用计数。

当服务器运行时，它会计算每个帐户使用资源的次数。如果帐户在过去一小时内达到其连接数限制，则服务器将拒绝该帐户的进一步连接，直到该小时结束。同样，如果帐户达到其查询或更新数量的限制，服务器将拒绝进一步的查询或更新，直到该小时结束。在所有这些情况下，服务器都会发出相应的错误消息。

资源计数发生在每个帐户，而不是每个客户。例如，如果您的帐户的查询限制为 50，则无法通过同时与服务器建立两个客户端连接来将限制增加到 100。在两个连接上发出的查询一起计算。

当前每小时资源使用计数可以为所有帐户全局重置，也可以为给定帐户单独重置：

-   要将所有帐户的当前计数重置为零，请发出[`FLUSH USER_RESOURCES`](flush.html#flush-user-resources)陈述。计数也可以通过重新加载授权表来重置（例如，使用[`刷新特权`](flush.html#flush-privileges)声明或[**mysqladmin 重新加载**](mysqladmin.html)命令）。

-   通过再次设置任何限制，可以将单个帐户的计数重置为零。指定一个等于当前分配给帐户的值的限制值。

    每小时计数器重置不影响`MAX_USER_CONNECTIONS`限制。

    当服务器启动时，所有计数都从零开始。计数不会通过服务器重新启动而结转。

    为了`MAX_USER_CONNECTIONS`限制，如果帐户当前已打开允许的最大连接数，则可能会发生边缘情况：断开连接后快速连接可能会导致错误（[`ER_TOO_MANY_USER_CONNECTIONS`](https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_too_many_user_connections)要么[`ER_USER_LIMIT_REACHED`](https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_user_limit_reached)) 如果在连接发生时服务器尚未完全处理断开连接。当服务器完成断开连接处理时，再次允许另一个连接。
