被我誤解的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」那太好辦了,故意輸錯密碼不就好了,而且網上搜索了下該參數的說明,大量的文章充斥着」 防止暴力破解密碼」的內容,因而興高采烈的去作了測試。如下測試基於自建的mysql(非rds for mysql),因爲rds for mysql沒法直接設置set global,設置時須要在"rds控制檯-參數這裏"裏進行設置:https://help.aliyun.com/document_detail/26179.html?spm=5176.11065259.1996646101.searchclickresult.44156de7pLffcVhtml

第二節  測試max_connect_errors

1,建立帳號:mysql

b984add34b00bee3d562d96d25fa07ccb8145a7a

2,設置max_connect_errors爲3:sql

4776ffe81ccffb4de40ab1daacd8220f5be822d2

3,故意輸錯密碼3次,第四次使用正確密碼登陸進行驗證:shell

f376ff16b8b381fcf71f4b79893db1fd11246e51

4,結論是第四次依然能夠登陸,即密碼不對(認證失敗)不屬於」 」without a successful connection」」的範疇,網上的」 防止暴力破解密碼」也不成立了。express

6cd06be24be4b24af171a2710d5f5e790f977cb3

第三節 繼續分析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.網絡

大意是:socket

當你遇到主機被阻止的時候,你能夠清空host cache來解決,具體的清空方法是執行flush hosts或者在mysql服務器的shell裏執行 mysqladmin flush-hosts操做tcp

既然清空host cache能夠解決主機被阻止訪問的問題,那應該與host cache有些關係,看看host cache的介紹可能會有些眉目,關於host cache,文檔解釋以下:oop

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). Only protocol handshake errors are counted, 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(鏈接錯誤計數)描述,重點是紅色部分:只計算協議握手過程的錯誤(Only protocol handshake errors are counted),也就是說max_connect_errors 可能記錄的是協議(不肯定是tcp協議仍是應用協議,經過抓包以及COUNT_HANDSHAKE_ERRORS的」 the wire protocol level」說明多是指應用協議)的握手過程當中出現的錯誤 ,也就是能夠說網絡很差(沒法順利握手)會致使該問題。

第四節 繼續測試max_connect_errors

經過以前的說明,須要模擬應用協議握手失敗的狀況,最後考慮使用telnet一些來作測試

1,建立帳號

b984add34b00bee3d562d96d25fa07ccb8145a7a

2,設置max_connect_errors爲3:

4776ffe81ccffb4de40ab1daacd8220f5be822d2

3,先使用telnet 10.26.254.217 3306鏈接3次,第四次使用正確的帳號密碼嘗試登錄:

telnet前查看performance_schema.host_cache的記錄爲空

95e4568e7fe1b5cb44a21b30a9aa9210ef9f0a73

第一次telnet 10.26.254.217 3306

bce33a3ea7394f8e1d564c3921d3f294dcd79814

052299fb80bdd456d12855a8f84689011f13ce51

第二次 telnet 10.26.254.217 3306

9ac1875beec55c02bedc86afcee78400f63745c5

f7a6d9e971fdc753d65c5b116b95ed45572e0d55

第三次telnet 10.26.254.217 3306

aa6232eaa401e0c1bfa5cdcfc0f2168c379ec97a

09f732c6269039549da6393138a09d99cee2a878

第四次執行mysql -h10.26.254.217 -utestcon -p123 -P3306

3bba32ab58c65de19d912febc805d13f407c93b8

fe47d609cfd83b0867b5a64232d1a6aae1011505

問題復現了,出現了錯誤提示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

2,打開skip-name-resolve 

須要經過測試看下推測是否生效

5.1 設置 host_cache_size 爲0/ 打開skip-host-cache

1,設置host_cache_size爲0

f0d9b5f93d58538762288eb6be86e8edb9cd6cab

2,再次查詢performance_schema.host_cache

44dd050f8f353a71d9563c3b38092d0cc0bb65a9

3,繼續以前的測試:先使用telnet 10.26.254.217 3306鏈接3次,第四次使用正確的帳號密碼嘗試登錄

5f889f9d574cf843a1423a12ac4a2d21b73d9f8d

更改已經生效,max_connect_errors的做用無效了

5.2 打開skip-name-resolve 

1,在cnf配置文件裏設置skip-name-resolve 以此打開skip-name-resolve 

123514e6b68f10befb209f4321c1ab82894fc7d3

2,繼續以前的測試:先使用telnet 10.26.254.217 3306鏈接3次,第四次使用正確的帳號密碼嘗試登錄

3fe7fac36742a2b9391267ab4936372a891e2d7a

3,查詢performance_schema.host_cache

4f308a50bcc5c27cb666b61228177261312cd0e0

更改已經生效,max_connect_errors的做用無效了,RDS for  mysql 的skip_name_resolve是on的狀態,

因此不多會出現ERROR 1129 (HY000)的錯誤

相關文章
相關標籤/搜索