限制客户端使用 MySQL 服务器资源的一种方法是将全局 max_user_connections
系统变量设置为非零值。这限制了任何给定帐户可以建立的同时连接数,但对客户端连接后可以做什么没有限制。此外,设置 max_user_connections
不会启用对单个帐户的管理。这两种类型的控制都是 MySQL 管理员感兴趣的。
为了解决这些问题,MySQL 允许对单个帐户使用以下服务器资源进行限制
一个帐户每小时可以发出的查询数
一个帐户每小时可以发出的更新数
一个帐户每小时可以连接到服务器的次数
一个帐户到服务器的同时连接数
客户端可以发出的任何语句都计入查询限制。只有修改数据库或表的语句才计入更新限制。
在这种情况下,“帐户”对应于 mysql.user
系统表中的一行。也就是说,连接是根据适用于该连接的 user
表行中的 User
和 Host
值进行评估的。例如,帐户 'usera'@'%.example.com'
对应于 user
表中 User
和 Host
值分别为 usera
和 %.example.com
的行,以允许 usera
从 example.com
域中的任何主机连接。在这种情况下,服务器将此行中的资源限制集体应用于 usera
从 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
子句中不需要列出所有限制类型,但列出的类型可以按任何顺序出现。每个每小时限制的值应为表示每小时计数的整数。对于 MAX_USER_CONNECTIONS
,限制是表示帐户同时连接最大数量的整数。如果此限制设置为零,则全局 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
限制为零。 user2
和 user3
的连接限制分别为 5 和 20,因为它们的 MAX_USER_CONNECTIONS
限制不为零。
服务器将帐户的资源限制存储在与该帐户对应的 user
表行中。 max_questions
、max_updates
和 max_connections
列存储每小时的限制,而 max_user_connections
列存储 MAX_USER_CONNECTIONS
限制。(请参阅 第 8.2.3 节“授权表”。)
当任何帐户对其使用任何资源设置了非零限制时,就会进行资源使用计数。
服务器运行时,它会统计每个帐户使用资源的次数。如果某个帐户在最后一小时内达到了其连接数限制,则服务器将拒绝该帐户的进一步连接,直到该小时结束。同样,如果该帐户达到了其查询或更新次数限制,则服务器将拒绝进一步的查询或更新,直到该小时结束。在所有这些情况下,服务器都会发出相应的错误消息。
资源计数是按帐户进行的,而不是按客户端进行的。例如,如果您的帐户的查询限制为 50,则不能通过建立到服务器的两个并发客户端连接来将限制增加到 100。两个连接上发出的查询将一起计数。
当前每小时的资源使用计数可以全局重置为所有帐户,也可以单独为给定帐户重置
要将所有帐户的当前计数重置为零,请发出
FLUSH USER_RESOURCES
语句。也可以通过重新加载授权表来重置计数(例如,使用FLUSH PRIVILEGES
语句或 mysqladmin reload 命令)。可以通过再次设置任何限制将其单个帐户的计数重置为零。指定一个等于当前分配给该帐户的值的限制值。
每小时计数器重置不会影响 MAX_USER_CONNECTIONS
限制。
所有计数在服务器启动时都从零开始。计数不会在服务器重启后保留。
对于 MAX_USER_CONNECTIONS
限制,如果帐户当前已打开允许其打开的最大连接数,则可能会出现边缘情况:如果服务器在连接发生时尚未完全处理断开连接,则快速断开连接后再连接可能会导致错误(ER_TOO_MANY_USER_CONNECTIONS
或 ER_USER_LIMIT_REACHED
)。当服务器完成断开连接处理后,将再次允许另一个连接。