限制用戶端使用 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
),如果伺服器在連線發生時尚未完全處理完斷開連線。當伺服器完成斷開連線處理後,再次允許另一個連線。