MySQL 伺服器維護一個記憶體內的主機快取,其中包含有關用戶端的資訊:IP 位址、主機名稱和錯誤資訊。效能結構描述 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()
系統呼叫執行主機名稱解析。
伺服器以下列方式處理主機快取中的項目
當第一個 TCP 用戶端連線從給定 IP 位址抵達伺服器時,會建立新的快取項目,以記錄用戶端 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
系統變數控制其大小,以及效能結構描述 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;
效能結構描述 host_cache
表格會公開主機快取的內容。可以使用 SELECT
陳述式檢查此表格,這可能有助於您診斷連線問題的原因。有關此表格的資訊,請參閱第 29.12.22.3 節「host_cache 表格」。
在以下情況下,清除主機快取可能是可取或需要的
您的一些用戶端主機變更 IP 位址。
來自合法主機的連線發生錯誤訊息
Host '
。(請參閱處理被封鎖的主機。)host_name
' is blocked
清除主機快取具有以下效果
它會清除記憶體中的主機快取。
它會從效能結構描述
host_cache
表格中移除所有列,該表格會公開快取內容。它會解除封鎖任何被封鎖的主機。這會允許來自這些主機的進一步連線嘗試。
若要清除主機快取,請使用下列任何一種方法
變更
host_cache_size
系統變數的值。這需要SYSTEM_VARIABLES_ADMIN
權限(或已棄用的SUPER
權限)。執行
TRUNCATE TABLE
陳述式,該陳述式會截斷效能結構描述host_cache
表格。這需要該表格的DROP
權限。執行 mysqladmin flush-hosts 命令。這需要效能結構描述
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
增加到較大的值,會降低主機達到閾值並被封鎖的可能性。然而,如果發生 Host '
錯誤訊息,請先驗證來自被封鎖主機的 TCP/IP 連線是否有任何問題。如果存在網路問題,則增加 host_name
' is blockedmax_connect_errors
的值並無益處。