6.2.16 设置帐户资源限制

限制 Client 端使用 MySQL 服务器资源的一种方法是将全局max_user_connections系统变量设置为非零值。这限制了任何给定帐户可以构建的同时连接数,但是对 Client 端一旦连接后可以执行的操作没有任何限制。此外,设置max_user_connections不会启用单个帐户的 Management。 MySQLManagement 员对这两种类型的控件都感兴趣。

为了解决这些问题,MySQL 允许限制使用这些服务器资源的个人帐户:

  • 帐户每小时可发出的查询数量

  • 帐户每小时可以发布的更新次数

  • 帐户每小时可以连接到服务器的次数

  • 帐户同时连接到服务器的数量

Client 端可以发出的任何语句都将计入查询限制,除非从查询缓存中提供其结果。只有修改数据库或 table 的语句才计入更新限制。

在这种情况下,“帐户”对应于mysql.user系统 table 中的一行。也就是说,将根据适用于该连接的usertable 行中的UserHost值评估连接。例如,帐户'usera'@'%.example.com'对应于usertable 中具有usera%.example.comUserHost值的行,以允许useraexample.com域中的任何主机进行连接。在这种情况下,由于example.com域中的任何主机,服务器将usera将此行中的资源限制集中应用于所有连接,因此usera都将使用该帐户。

在 MySQL 5.0 之前,“帐户”是根据用户连接的实际主机进行评估的。可以通过使用--old-style-user-limits选项启动服务器来选择这种较旧的记帐方法。在这种情况下,如果userahost1.example.comhost2.example.com同时连接,则服务器将帐户资源限制分别应用于每个连接。如果userahost1.example.com重新连接,服务器将应用该连接的限制以及该主机的现有连接。

要在帐户创建时为帐户构建资源限制,请使用CREATE USER语句。要修改现有帐户的限制,请使用ALTER USER。提供一个WITH子句,命名每个要限制的资源。每个限制的默认值为零(无限制)。例如,要创建一个可以访问customer数据库但仅以受限方式访问的新帐户,请发出以下语句:

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;

限制类型不必全部在WITH子句中命名,但是可以以任何 Sequences 出现。每个小时限制的值应为代 table 每小时计数的整数。对于MAX_USER_CONNECTIONS,该限制是一个整数,代 table 该帐户的最大同时连接数。如果此限制设置为零,则全局max_user_connections系统变量值将确定同时连接的数量。如果max_user_connections也是零,则该帐户没有限制。

要修改现有帐户的限额,请使用ALTER USER语句。以下语句将francis的查询限制更改为 100:

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

该语句仅修改指定的限制值,而使帐户保持不变。

要删除限制,请将其值设置为零。例如,要消除每小时francis可以连接多少次的限制,请使用以下语句:

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

如前所述,帐户的同时连接限制由MAX_USER_CONNECTIONS限制和max_user_connections系统变量确定。假设全局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;

user1的连接限制为 10(全局max_user_connections值),因为它的MAX_USER_CONNECTIONS限制为零。 user2user3的连接限制分别为 5 和 20,因为它们的非MAX_USER_CONNECTIONS限制为非零。

服务器在对应于该帐户的usertable 行中存储该帐户的资源限制。 max_questionsmax_updatesmax_connections列存储每小时限制,而max_user_connections列存储MAX_USER_CONNECTIONS限制。 (请参阅第 6.2.3 节“授权 table”。)

当任何帐户对任何资源的使用设置非零限制时,就会进行资源使用计数。

服务器运行时,它会计算每个帐户使用资源的次数。如果一个帐户在最后一个小时内达到其连接数限制,则服务器将拒绝该帐户的其他连接,直到该小时为止。同样,如果帐户达到查询或更新次数的限制,则服务器将拒绝其他查询或更新,直到小时。在所有这些情况下,服务器都会发出适当的错误消息。

资源计数是针对每个帐户而不是每个 Client 端进行的。例如,如果您的帐户的查询限制为 50,则无法通过同时构建两个 Client 端到服务器的连接来将限制增加到 100.在两个连接上发出的查询将一起计算。

可以为所有帐户全局重置当前的每小时资源使用计数,或者为给定帐户单独重置:

  • 要将所有帐户的当前计数重置为零,请发出FLUSH USER_RESOURCES语句。也可以通过重新加载授权 table(例如,使用FLUSH PRIVILEGES语句或mysqladmin reload命令)来重置计数。

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

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

服务器启动时,所有计数均从零开始。计数不会通过服务器重新启动而保留。

对于MAX_USER_CONNECTIONS限制,如果该帐户当前已打开了允许的最大连接数,则可能会出现极端情况:如果服务器未完全处理以下错误,则先断开连接然后再进行连接会导致错误(ER_TOO_MANY_USER_CONNECTIONSER_USER_LIMIT_REACHED)。连接发生时断开连接。服务器完成断开连接处理后,将再次允许另一个连接。