MySQL 伺服器會維護一個記憶體內的主機快取,其中包含關於用戶端的資訊:IP 位址、主機名稱和錯誤資訊。Performance Schema host_cache
表格會公開主機快取的內容,以便可以使用 SELECT
陳述式來檢查。這可能協助您診斷連線問題的原因。請參閱第 29.12.22.3 節「host_cache 表格」。
以下章節討論主機快取如何運作,以及其他主題,例如如何設定和監控快取。
伺服器僅針對非本機主機 TCP 連線使用主機快取。它不會針對使用迴路介面位址 (例如,127.0.0.1
或 ::1
) 建立的 TCP 連線,或針對使用 Unix Socket 檔案、具名管道或共享記憶體建立的連線使用快取。
伺服器使用主機快取有多個目的
透過快取 IP 對主機名稱查詢的結果,伺服器可避免針對每個用戶端連線執行網域名稱系統 (DNS) 查詢。相反地,針對給定的主機,它只需要針對來自該主機的第一個連線執行查詢。
快取包含關於用戶端連線程序期間發生的錯誤的資訊。某些錯誤被視為「封鎖」。如果從給定的主機連續發生太多此類錯誤而沒有成功連線,則伺服器會封鎖來自該主機的進一步連線。
max_connect_errors
系統變數會決定封鎖發生前允許的連續錯誤次數。
對於每個適用的新客戶端連線,伺服器會使用客戶端的 IP 位址來檢查主機名稱是否在主機快取中。如果是,伺服器會根據主機是否被封鎖,決定拒絕或繼續處理連線請求。如果主機不在快取中,伺服器會嘗試解析主機名稱。首先,它會將 IP 位址解析為主機名稱,然後將該主機名稱解析回 IP 位址。接著,它會將結果與原始 IP 位址進行比較,以確保兩者相同。伺服器會將此操作的結果資訊儲存在主機快取中。如果快取已滿,則會丟棄最近最少使用的項目。
伺服器使用 getaddrinfo()
系統呼叫來執行主機名稱解析。
伺服器以這種方式處理主機快取中的項目
當第一個來自特定 IP 位址的 TCP 客戶端連線到達伺服器時,會建立一個新的快取項目,以記錄客戶端 IP、主機名稱和客戶端查詢驗證標誌。最初,主機名稱設定為
NULL
,而標誌為 false。此項目也用於來自相同來源 IP 的後續客戶端 TCP 連線。如果客戶端 IP 項目的驗證標誌為 false,伺服器會嘗試 IP 到主機名稱再到 IP 的 DNS 解析。如果成功,則會使用已解析的主機名稱更新主機名稱,並將驗證標誌設定為 true。如果解析不成功,則採取的動作取決於錯誤是永久性還是暫時性。對於永久性失敗,主機名稱將保持
NULL
,驗證標誌設定為 true。對於暫時性失敗,主機名稱和驗證標誌保持不變。(在這種情況下,下次客戶端從此 IP 連線時,會再次嘗試 DNS 解析。)如果在處理來自特定 IP 位址的傳入客戶端連線時發生錯誤,伺服器會更新該 IP 項目中對應的錯誤計數器。有關記錄的錯誤的描述,請參閱第 29.12.22.3 節「host_cache 表格」。
若要解除封鎖遭封鎖的主機,請清除主機快取;請參閱處理遭封鎖的主機。
即使沒有清除主機快取,如果發生來自其他主機的活動,遭封鎖的主機仍有可能解除封鎖
如果當來自快取中不存在的客戶端 IP 的連線到達時,快取已滿,伺服器會丟棄最近最少使用的快取項目,以便為新項目騰出空間。
如果丟棄的項目是針對遭封鎖的主機,則該主機會解除封鎖。
某些連線錯誤與 TCP 連線無關,在連線過程的早期發生(甚至在已知 IP 位址之前),或者不是特定於任何特定 IP 位址(例如記憶體不足的情況)。有關這些錯誤的資訊,請檢查 Connection_errors_
狀態變數(請參閱第 7.1.10 節「伺服器狀態變數」)。xxx
主機快取預設為啟用。 host_cache_size
系統變數控制其大小,以及公開快取內容的 Performance Schema host_cache
表格的大小。快取大小可以在伺服器啟動時設定,並在執行時變更。例如,若要在啟動時將大小設定為 100,請將下列幾行放入伺服器 my.cnf
檔案中
[mysqld]
host_cache_size=200
若要在執行時將大小變更為 300,請執行此動作
SET GLOBAL host_cache_size=300;
在伺服器啟動時或執行時將 host_cache_size
設定為 0,會停用主機快取。停用快取後,伺服器每次客戶端連線時都會執行 DNS 查閱。
在執行時變更快取大小會導致隱式主機快取清除操作,該操作會清除主機快取、截斷 host_cache
表格,並解除封鎖任何遭封鎖的主機;請參閱清除主機快取。
若要停用 DNS 主機名稱查閱,請在啟用 skip_name_resolve
系統變數的情況下啟動伺服器。在這種情況下,伺服器僅使用 IP 位址,而不使用主機名稱,來將連線主機與 MySQL 授與表格中的資料列進行比對。只能使用這些表格中使用 IP 位址指定的帳戶。(如果不存在指定客戶端 IP 位址的帳戶,客戶端可能無法連線。)
如果您擁有非常慢的 DNS 和許多主機,您可以藉由啟用 skip_name_resolve
來停用 DNS 查閱,或者藉由增加 host_cache_size
的值,以使主機快取更大,來提高效能。
若要完全禁止 TCP/IP 連線,請在啟用 skip_networking
系統變數的情況下啟動伺服器。
若要調整在發生主機封鎖之前允許的連續連線錯誤次數,請設定 max_connect_errors
系統變數。例如,若要在啟動時設定值,請將下列幾行放入伺服器 my.cnf
檔案中
[mysqld]
max_connect_errors=10000
若要在執行時變更值,請執行此動作
SET GLOBAL max_connect_errors=10000;
Performance Schema host_cache
表格公開主機快取的內容。可以使用 SELECT
陳述式檢查此表格,這可能有助于您診斷連線問題的原因。有關此表格的資訊,請參閱第 29.12.22.3 節「host_cache 表格」。
在下列情況下,清除主機快取可能是明智或可取的
您的一些客戶端主機變更了 IP 位址。
來自合法主機的連線發生錯誤訊息
主機 '
。(請參閱處理遭封鎖的主機。)host_name
' 已封鎖
清除主機快取會產生以下影響
它會清除記憶體中的主機快取。
它會從 Performance Schema
host_cache
表格中移除所有資料列,該表格會公開快取內容。它會解除封鎖任何遭封鎖的主機。這會允許這些主機進一步嘗試連線。
若要清除主機快取,請使用下列任何一種方法
變更
host_cache_size
系統變數的值。這需要SYSTEM_VARIABLES_ADMIN
權限(或已淘汰的SUPER
權限)。執行一個
TRUNCATE TABLE
陳述式,該陳述式會截斷 Performance Schemahost_cache
表格。這需要該表格的DROP
權限。執行 mysqladmin flush-hosts 命令。這需要 Performance Schema
host_cache
表格的DROP
權限,或RELOAD
權限。
伺服器使用主機快取來追蹤客戶端連線過程中發生的錯誤。如果發生以下錯誤,則表示 mysqld 已收到來自指定主機的許多連線請求,這些請求在中途被中斷
Host 'host_name' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'
系統變數 max_connect_errors
的值決定了伺服器在封鎖主機之前允許多少個連續中斷的連線請求。在 max_connect_errors
次失敗的請求而沒有成功連線後,伺服器會假設有問題(例如,有人試圖闖入),並封鎖該主機的進一步連線請求。
若要解除封鎖遭封鎖的主機,請清除主機快取;請參閱清除主機快取。
或者,若要避免發生錯誤訊息,請如設定主機快取中所述,設定 max_connect_errors
。max_connect_errors
的預設值為 100。將 max_connect_errors
增加到較大的值,可以降低主機達到閾值並被封鎖的可能性。但是,如果出現 主機 '
錯誤訊息,請先確認來自遭封鎖主機的 TCP/IP 連線沒有任何問題。如果存在網路問題,增加 host_name
' 已封鎖max_connect_errors
的值沒有任何好處。