被我誤解的max_connect_errors
實為吾之愚見,望諸君酌之!聞過則喜,與君共勉
第一節 什麼是max_connect_errors
一開始接觸這個參數的時候,感覺他和max_connections的含義差不多,字麵意思簡單明了,這個參數的含義是最大連接錯誤數,翻翻mysql的文檔中的解釋是If more than this many successive connection requests from a host are interrupted without a successful connection, the server blocks that host from further connections,大意是:如果mysql服務器連續接收到了來自於同一個主機的請求,且這些連續的請求全部都沒有成功的建立連接就被斷開了,當這些連續的請求的累計值大於 max_connect_errors的設定值時,mysql服務器就會阻止這台主機後續的所有請求。”without a successful connection”那太好辦了,故意輸錯密碼不就行了,並且網上搜索了下該參數的說明,大量的文章充斥著” 防止暴力破解密碼”的內容,於是興高采烈的去做了測試。
第二節 測試max_connect_errors
1,創建賬號:
2,設置max_connect_errors為3:
3,故意輸錯密碼3次,第四次使用正確密碼登錄進行驗證:
4,結論是第四次依然可以登錄,即密碼不對(認證失敗)不屬於” ”without a successful connection””的範疇,網上的” 防止暴力破解密碼”也不成立了。
第三節
繼續分析max_connect_errors
再繼續看文檔,發現還有以下說明:
You can unblock blocked hosts by flushing
the host cache. To do so, issue a FLUSH HOSTS
statement or execute a mysqladmin flush-hosts command.
大意是:
當你遇到主機被阻止的時候,你可以清空host cache來解決,具體的清空方法是執行flush hosts或者在mysql服務器的shell裏執行 mysqladmin flush-hosts操作
既然清空host cache可以解決主機被阻止訪問的問題,那應該與host cache有些關係,看看host cache的介紹可能會有些眉目,關於host cache,文檔解釋如下:
The MySQL server maintains a host cache in
memory that contains information about clients: IP address, host name, and
error information. The server uses this cache for nonlocal TCP connections. It
does not use the cache for TCP connections established using a loopback
interface address (127.0.0.1
or ::1
), or for connections established using a Unix
socket file, named pipe, or shared memory.
大意是:
Mysql服務器會在內存裏管理一個host cache,host cache裏保存了一些客戶端的ip地址,主機名,以及這個客戶端在與server建立連接時遇到的一些錯誤信息,host cache對不是本地的TCP連接才有效,所以host cache對127.0.0.1
或者::1
是無效的,並且對於
Unix socket file、named pipe以及 shared memory方式建立的連接也是無效的。並且通過了解,host cache的內容可以通過performance_schema.host_cache來查看,通過performance_schema.host_cache表裏的幾個列的描述信息,對之前的測試不成立的原因有些了解了,部分相關列如下:
· IP
The IP address of the client that connected to the server, expressed as a string.
連接到mysql server的主機的連接地址
· HOST
The resolved DNS host name for that client IP, or NULL if the name is unknown.
通過dns解析IP地址獲取到的該IP地址對應的mysql client的主機名
· SUM_CONNECT_ERRORS
The number of connection errors that are deemed “blocking” (assessed against the max_connect_errors system variable). , and only for hosts that passed validation (HOST_VALIDATED = YES).
· COUNT_HANDSHAKE_ERRORS
The number of errors detected at the wire protocol level.
通過SUM_CONNECT_ERRORS(連接錯誤計數)描述,重點是紅色部分:隻計算協議握手過程的錯誤(),也就是說max_connect_errors 可能記錄的是協議(不確定是tcp協議還是應用協議,通過抓包以及COUNT_HANDSHAKE_ERRORS的” the wire protocol level”說明可能是指應用協議)的握手過程中出現的錯誤 ,也就是可以說網絡不好(無法順利握手)會導致該問題。
第四節 繼續測試max_connect_errors
通過之前的說明,需要模擬應用協議握手失敗的情況,最後考慮使用telnet一些來做測試
1,創建賬號
2,設置max_connect_errors為3:
3,先使用telnet 10.26.254.217 3306連接3次,第四次使用正確的賬號密碼嚐試登陸:
telnet前查看performance_schema.host_cache的記錄為空
第三次telnet 10.26.254.217 3306
第四次執行mysql -h10.26.254.217 -utestcon -p123 -P3306
問題複現了,出現了錯誤提示ERROR 1129 (HY000): Host '10.24.236.231' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
第五節 ERROR 1129 (HY000)問題延伸
解決ERROR 1129 (HY000)的方法是執行flush host或者 mysqladmin flush-hosts,其目的是為了清空host cache裏的信息,那是不是說不使用host cache就可以了?使host cache不生效的方式有如下兩種:
1,設置 host_cache_size
為0/ 打開skip-host-cache
需要通過測試看下推測是否生效
5.1 設置 host_cache_size
為0/ 打開skip-host-cache
1,設置host_cache_size
為0
2,再次查詢performance_schema.host_cache
3,繼續之前的測試:先使用telnet 10.26.254.217 3306連接3次,第四次使用正確的賬號密碼嚐試登陸
更改已經生效,max_connect_errors
的作用無效了
5.2 打開skip-name-resolve
1,在cnf配置文件裏設置skip-name-resolve
以此打開skip-name-resolve
2,繼續之前的測試:先使用telnet 10.26.254.217 3306連接3次,第四次使用正確的賬號密碼嚐試登陸
3,查詢performance_schema.host_cache
更改已經生效,max_connect_errors
的作用無效了,RDS for mysql 的skip_name_resolve是on的狀態,
所以很少會出現ERROR 1129 (HY000)的錯誤
最後更新:2017-08-13 22:34:01