翻譯:MySQL "Got an Error Reading Communication Packet" Errors


前言: 本文是對Muhammad Irfan的這篇博客MySQL "Got an Error Reading Communication Packet" Errors的翻譯,如有翻譯不對或不好的地方,敬請指出,大家一起學習進步。尊重原創和翻譯勞動成果,轉載時請注明出處。謝謝!

 

 

英文原文地址:https://www.percona.com/blog/2016/05/16/mysql-got-an-error-reading-communication-packet-errors/

 

 

翻譯原文地址:http://www.cnblogs.com/kerrycode/p/9075214.html

 

 

 

在這篇博客中,我們來討論一下引起MySQL出現Got an error reading communication packet錯誤的可能原因,以及如何解決這個錯誤。

 

Percona的托管服務中,我們經常收到客戶關於通信故障錯誤的問題客戶面臨間歇性的Got an error reading communication packet錯誤,我認為這個話題值得寫一篇博客,所以我們在這里討論這個錯誤出現的可能原因,以及如何解決這個問題。我希望這些能夠幫助讀者如何調查和解決這個問題。

 

首先,當通信故障錯誤出現時,MySQL的狀態變量Aborted_clientsAborted_connects的計數會增加。這兩個狀態變量描述了由於客戶端沒有正確關閉連接而導致中斷的連接數以及那些嘗試登錄MySQL失敗的連接數量(分別)。兩個錯誤出現的可能原因很多(請參考官方文檔關於Aborted_clients increments or Aborted_connects increments 章節)。

 

在系統變量log_warnings > 1的情況下,MySQL會將這些信息寫入錯誤日志(如下所示):

 

[Warning] Aborted connection 305628 to db: 'db' user: 'dbuser' host: 'hostname' (Got an error reading communication packets)

[Warning] Aborted connection 305627 to db: 'db' user: 'dbuser' host: 'hostname' (Got an error reading communication packets)

 

 

在下面這些情況下, MySQL會增加Aborted_clients狀態變量的計數,這可能意味着:

 

o    客戶端已經成功連接,但是異常終止了(可能與未正確關閉連接有關系)

o    客戶端休眠時間超過了系統變量wait_timeoutinteractive_timeout的定義值(最終導致連接休眠的時間超過系統變量wait_timeout的值,然后被MySQL強行關閉)

o    客戶端異常中斷或查詢超出了max_allowed_packet值。

 

上面不是一個包括了全部可能原因的列表,現在,我們來聊聊如何識別導致這個問題的原因以及如何解決這個。

 

我們如何識別導致此問題的原因,以及如何解決、修復這個問題呢?

 

 

老實來說,連接中斷錯誤不容易診斷,但根據我的經驗,大部分時候它跟網絡/防火牆問題有關,我們通常在Percona Toolkit腳本的幫助下來調查這些問題。例如pt-summary / pt-mysql-summary / pt-stalk 這些腳本的輸出信息非常有幫助。

 

其中的一些可能原因:

 

MySQL內部,大量的MySQL連接處於休眠狀態並休眠了數百秒是應用程序在完成工作后沒有關閉連接的症狀之一,它們依靠wait_tiemout系統變量來關閉連接。 我強烈建議修改應用程序邏輯,在操作結束后正確關閉連接。

 

檢查並確保max_allowed_packet的值足夠大,並且客戶端沒有收到packet Too large這種消息,這種情況會導致連接中斷而無法正常關閉連接。

 

另外一種可能性是TIME_WAIT, 我注意到了許多來自netstatTIME_WAIT通知,所以我建議在應用程序端管理好連接並關閉連接。

 

確保事務正確的提交(begin commit),以便一旦應用程序完成后,它保持干凈狀態。

 

你應該確保客戶端應用程序不會終止連接。 例如,如果PHP將選項max_execution_time設置成5秒,則增加connection_timeout將無濟於事, 因為PHP將終止該腳本。其它編程語言和環境可能有類似的安全選項。

 

引起連接延遲的另外一個原因是DNS問題,檢查是否啟用了跳過名稱解析,以及主機是否針對其IP地址而不是其主鍵名進行身份驗證。

 

找出應用程序錯誤行為的一種方法在代碼中增加一些日志記錄,以便將應用程序的操作與MySQL連接標識信息一起保存。這樣你可以將它與錯誤行中的連接號關聯起來。啟用PerConna審計日志插件(Audit log plugin),記錄連接和查詢活動,並在你遇到連接中斷時檢查Percona Audit Log Plugin的日志,以確定哪個查詢是罪魁禍首。如果你由於某種原因不能使用Audit插件,你可以考慮使用MySQL的查詢日志,盡管在負荷較高的服務器可能有風險, 你也應該啟用查詢日志至少幾分鍾。雖然它給服務器帶來了沉重的負擔,由於錯誤往往會經常發生,所以你應該能夠在日志變得過大前收集到所需的數據,我建議使用啟用查詢日志並使用tail -f來查看查詢日志,當你在查詢日志中看到下一個告警出現時,就禁用查詢日志。

 

 

一旦你從中斷的連接中找到一些查詢語句后,在應用程序中找到使用這些查詢的相關應用程序部分。

 

 

嘗試增加MySQL的系統變量net_read_timeout net_write_timeout 的值,看看是否會減少錯誤的數量,net_read_timeout是很少出現的異常,除非你的網絡環境實在是太糟糕了,嘗試調整這些值,因為在大多數情況下,會生成一個查詢並將其作為單個數據包發送到服務器,並且應用程序無法切換到執行其他操作,而將服務器保留作為部分接收的查詢。我們的首席執行官Peter Zaitsev關於這個話題有一篇非常詳細的博客文章

 

 

中斷連接的出現是因為連接未正確關閉。除非服務器和客戶端直接存在網絡問題(例如,服務器是半雙工,客戶端是全雙工),否則服務器不會導致連接中斷,所以引起問題的是網絡,而不是服務器,在任何情況下,這些問題應該顯示為網絡接口上的錯誤,為了更加確定,請在MySQL服務器上使用ifconfig -a命令輸出相關信息。以檢查是否有錯誤。

 

解決這個問題的另外一個方法是通過tcpdump工具,你可以參考這篇博客,了解如何追蹤連接中斷的來源,查找潛在的網絡問題、超時和與 MySQL 相關的資源問題。

 

我發現這篇博客對解釋如何在繁忙的主機上使用tcpdump非常有用,它為跟蹤導致中止連接的TCP交換序列提供了幫助,這可以幫助您找出連接斷開的原因。

 

對於網絡問題,使用ping命令計算mysqld所在的服務器與應用程序發出請求的機器之間的往返時間(RTT),從客戶端向服務器發送大文件(1GB或更大),使用tcpdump觀察進程,然后檢查傳輸過程中是否發生錯誤。重復這個測試。我也從我的同事Marco Tusa那里找到了這個有用的方法:  檢查網絡連接的有效方法。

 

對於網絡問題,使用ping來計算mysqld所在的機器與應用程序發出請求的機器之間的往返時間(RTT)。向客戶機和服務器機器發送大文件(1GB或更多),使用tcpdump觀察進程,然后檢查傳輸過程中是否發生錯誤。重復這個測試幾次。我也從我的同事Marco Tusa那里找到了這個有用的方法:檢查網絡連接的有效方法

 

我能想到的另一個想法是在每N秒后捕獲一次netstat -s輸出和一個時間戳(例如,10秒鍾,這樣您就可以將BEFOREAFTER中斷連接錯誤的netstat -s輸出與MySQL錯誤日志相關聯) 。通過中斷連接錯誤的時間戳,您可以將它與根據netstat時間戳記捕獲的netstat示例進行共同關聯,並觀察在netstat -sTcpExt部分下增加了哪些錯誤計數器。

 

除此之外,還應該檢查位於客戶端和服務器之間的網絡基礎架構,從代理(proxies),負載平衡器和防火牆那些可能導致問題的方面入手。

 

 

 

結論:

 

    我試圖涵蓋通信失敗錯誤(communication failure errors),以及如何識別和修復可能的連接中斷問題。考慮到以太網,集線器,交換機,電纜等故障也會導致此問題。您必須更換硬件才能正確診斷這些問題。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM