ERROR 2013 (HY000): Lost connection to MySQL server at 'reading authorization packet', system error:

最近遇到一個MySQL鏈接的問題,遠程鏈接MySQL時遇到ERROR 2013 (HY000): Lost connection to MySQL server at 'reading authorization packet', system error: 0錯誤,以下所示:html

 

[root@DB-Server ~]# mysql -h 10.13.65.93 -u onecard -pmysql

Enter password: sql

ERROR 2013 (HY000): Lost connection to MySQL server at 'reading authorization packet', system error: 0數據庫

 

這個測試的MySQL位於阿里雲Kubernetes(K8s)中Docker容器裏面,並且在遠程鏈接MySQL出現上面錯誤的時候,Docker也會出現下面錯誤。服務器

 

clip_image001

 

通常出現ERROR 2013 (HY000): Lost connection to MySQL server at 'reading authorization packet'錯誤的緣由較多:網絡

 

1:網絡異常或時延很是高的時候, 超過鏈接時間限制(系統變量connect_timeout)會致使這個錯誤。MySQL客戶端與數據庫創建鏈接須要發起三次握手協議,正常狀況下,這個時間很是短,可是一旦網絡異常,網絡超時等因素出現,就會致使這個握手協議沒法完成,MySQL有個參數connect_timeout,它是MySQL服務端進程mysqld等待鏈接創建完成的時間,單位爲秒。若是超過connect_timeout時間範圍內,仍然沒法完成協議握手話,MySQL客戶端會收到異常。  更多詳細信息能夠參考我這篇博客MySQL參數max_connect_errors分析釋疑,可是當前這個案例中,不存在網絡延時狀況,以下所示:app

 

[root@DB-Server ~]# ping 10.13.65.93
PING 10.13.65.93 (10.13.65.93) 56(84) bytes of data.
64 bytes from 10.13.65.93: icmp_seq=1 ttl=97 time=36.1 ms
64 bytes from 10.13.65.93: icmp_seq=2 ttl=97 time=36.3 ms
64 bytes from 10.13.65.93: icmp_seq=3 ttl=97 time=36.1 ms
64 bytes from 10.13.65.93: icmp_seq=4 ttl=97 time=36.0 ms
64 bytes from 10.13.65.93: icmp_seq=5 ttl=97 time=36.1 ms
64 bytes from 10.13.65.93: icmp_seq=6 ttl=97 time=36.2 ms
64 bytes from 10.13.65.93: icmp_seq=7 ttl=97 time=36.1 ms
64 bytes from 10.13.65.93: icmp_seq=8 ttl=97 time=36.2 ms
 
--- 10.13.65.93 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 7003ms
rtt min/avg/max/mdev = 36.092/36.205/36.354/0.205 ms

 

clip_image002

 

 

 

2:域名解析會致使這個問題。當客戶端鏈接上來,服務器端都會對客戶端進來的IP地址進行DNS解析,來得到客戶端的域名或主機名,若是DNS解析出了問題或DNS解析至關慢,就會致使鏈接驗證用戶出現問題。而skip-name-resolve這個參數的意義就是禁止域名解析。官方文檔解釋以下:測試

 

 

For each new client connection, the server uses the client IP address to check whether the client host name is in the host cache. If so, the server refuses or continues to process the connection request depending on whether or not the host is blocked. If the host is not in the cache, the server attempts to resolve the host name. First, it resolves the IP address to a host name and resolves that host name back to an IP address. Then it compares the result to the original IP address to ensure that they are the same. The server stores information about the result of this operation in the host cache. If the cache is full, the least recently used entry is discarded.this

The server handles entries in the host cache like this:阿里雲

 

  • When the first TCP client connection reaches the server from a given IP address, a new cache entry is created to record the client IP, host name, and client lookup validation flag. Initially, the host name is set to NULL and the flag is false. This entry is also used for subsequent client TCP connections from the same originating IP.

 

 當有一個新的客戶端鏈接經過TCP進來時,MySQL Server會爲這個IP在host cache中創建一個新的記錄,包括IP,主機名和client lookup validation flag,分別對應host_cache表中的IP,HOST和HOST_VALIDATED這三列。第一次創建鏈接由於只有IP,沒有主機名,因此HOST將設置爲NULL,HOST_VALIDATED將設置爲FALSE。

 

  • If the validation flag for the client IP entry is false, the server attempts an IP-to-host name-to-IP DNS resolution. If that is successful, the host name is updated with the resolved host name and the validation flag is set to true. If resolution is unsuccessful, the action taken depends on whether the error is permanent or transient. For permanent failures, the host name remains NULL and the validation flag is set to true. For transient failures, the host name and validation flag remain unchanged. (In this case, another DNS resolution attempt occurs the next time a client connects from this IP.)

 

    MySQL Server檢測HOST_VALIDATED的值,若是爲FALSE,它會試圖進行DNS解析,若是解析成功,它將更新HOST的值爲主機名,並將HOST_VALIDATED值設爲TRUE。若是沒有解析成功,判斷失敗的緣由是永久的仍是臨時的,若是是永久的,則HOST的值依舊爲NULL,且將HOST_VALIDATED的值設置爲TRUE,後續鏈接再也不進行解析,若是該緣由是臨時的,則HOST_VALIDATED依舊爲FALSE,後續鏈接會再次進行DNS解析。

 

  • If an error occurs while processing an incoming client connection from a given IP address, the server updates the corresponding error counters in the entry for that IP. For a description of the errors recorded, see Section 26.12.17.1, 「The host_cache Table」.  

         若是在處理來自給定IP地址的傳入客戶端鏈接時發生錯誤,則服務器會更新該IP條目中的相應錯誤計數器。 有關記錄的錯誤的說明,請參見第26.12.17.1節host_cache表

 

 

 

這個案例裏面,由於MySQL位於阿里雲Kubernetes(K8s)中Docker容器裏面,對公司內部的IP地址進行DNS解析確實會出現問題。咱們在配置文件設置skip_name_resolve後,確實解決了這個問題。而後原本覺得找到了緣由的我,在本地兩臺機器上測試時發現(一臺MySQL版本爲5.6.41, 一臺MySQL版本爲5.6.23),即便兩臺服務器相互不能作DNS解析,以下截圖所示,可是從192.168.27.180鏈接DB-Server時,並不會報這個錯誤。Why 即便我將connect_timeout調整爲2,依然不會出現這個錯誤。看來MySQL的鏈接不像咱們表面看的那樣簡單。仍是至關複雜。只是目前的技術水平,還作不到進一步分析!

 

 

clip_image003

 

另外,在這個案例的測試過程當中,發現skip_name_resolveOFF的狀況下,將connect_timeout設大,也不會出現這個錯誤

 

mysql>  show variables like '%connect_timeout%';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| connect_timeout | 10    |
+-----------------+-------+
1 row in set (0.01 sec)
 
mysql> set global connect_timeout=30;
Query OK, 0 rows affected (0.00 sec)
 
mysql> 

 

 

而後從客戶端鏈接MySQL數據庫就成功了,以下所示,只是IP地址並非客戶端的IP地址,而是Port IP

 

image

 

 固然這種狀況下Kubernetes(K8s)中Docker下MySQL並無掛掉,反而當系統變量connect_timeout=10的狀況下,若是沒有開啓系統變量skip_name_resolve,每次遠程鏈接MySQL就會出現Kubernetes(K8s)中Docker下MySQL掛掉,重啓的過程,因此極度懷疑是疑由於在鏈接過程,Docker下MySQL掛掉重啓纔出現這個錯誤。可是對K8s瞭解很少,涉及太廣,無法進一步分析具體緣由了。

相關文章
相關標籤/搜索