Aborted connection 1055898 to db: 'xxx' user: 'yyy' host: 'xxx.xxx.xxx.xxx' (Got timeout reading communication packets)
mysql錯誤日誌中,發現大量以下類似信息:(mysql 5.7.18)
[Note] Aborted connection 1055898 to db: ‘xxx‘ user: ‘yyy‘ host: ‘xxx.xxx.xxx.xxx‘ (Got timeout reading communication packets)
這種Aborted connection情況下,mysql會增加aborted_clients狀態計數器的值。這也意味著以下幾個問題:
(1)客戶端正常連接,但是被異常結束(可能是程序沒有正常關閉連接)
(2)客戶端sleep的時間超過了wait_timeout、或interactive_timeout的值(這會導致連接被mysql強制關閉)
(3)客戶端異常終端,或者查詢超出max_allowed_packet的值
mysql> show variables like ‘%max_allowed_packet%‘; +--------------------------+------------+ | Variable_name | Value | +--------------------------+------------+ | max_allowed_packet | 16777216 | | slave_max_allowed_packet | 1073741824 | +--------------------------+------------+
當然,也可能是其它原因導致的。坦白講,異常終端是很難診斷的,也有可能是和網絡、防火墻有關。可以從以下幾個方面考慮:
1.如果有大量的連接進程處於sleep狀態時間較長,也就意味著應用沒有正確、及時關閉數據庫連接。強烈建議在應用中能恰當地關閉數據庫連接,否則就需要依賴mysql的wait_timeout的設置來關閉連接了。
2.建議檢查max_allowed_packet的值,確保該值設置的合理,這樣客戶端就不會接收到"packet too large"消息提示。如果設置不合理,會異常中斷連接。
3.建議關註進程的time_wait數量。如果netstat發現有大量的連接處於time_wait狀態,表示該建議應用端調整連接關閉問題了。
# netstat -ano|grep TIME_WAIT tcp 0 0 xxx.xxx.xxx.xxx:10054 xxx.xxx.xxx.xxx:55586 TIME_WAIT timewait (32.97/0/0) tcp 0 0 xxx.xxx.xxx.xxx:10054 xxx.xxx.xxx.xxx:55367 TIME_WAIT timewait (27.82/0/0) tcp 0 0 xxx.xxx.xxx.xxx:10054 xxx.xxx.xxx.xxx:55776 TIME_WAIT timewait (37.09/0/0) tcp 0 0 xxx.xxx.xxx.xxx:10054 xxx.xxx.xxx.xxx:56505 TIME_WAIT timewait (54.61/0/0) tcp 0 0 xxx.xxx.xxx.xxx:10054 xxx.xxx.xxx.xxx:55553 TIME_WAIT timewait (31.94/0/0) tcp 0 0 xxx.xxx.xxx.xxx:10054 xxx.xxx.xxx.xxx:56643 TIME_WAIT timewait (57.73/0/0) tcp 0 0 xxx.xxx.xxx.xxx:10054 xxx.xxx.xxx.xxx:55221 TIME_WAIT timewait (23.70/0/0) tcp 0 0 xxx.xxx.xxx.xxx:10054 xxx.xxx.xxx.xxx:55920 TIME_WAIT timewait (41.18/0/0)
4.確保事務被正確、及時地提交了。
5.確保應用端沒有異常中斷連接,比如php如果設置了max_execution_time=5,即使你增加connect_timeout的值也不會有效果。其它編程語言也會有類似的問題。
6.檢查DNS配置是否有延遲問題。檢查是否同時配置了skip_name_resolve,且使用IP驗證主機而不是使用主機名。設置該參數後,使用ip驗證主機,而不是使用主機名。使用該參數後,mysql授權表中的host列必須是IP地址或者localhost。
7.如果是percona,可以開啟審計日誌。
8.增加net_read_timeout、net_write_timeout的值,並觀察是否還有該錯誤發生。net_read_timeout很少會導致出錯,除非網絡環境非常差。
連接異常終端是因為連接沒有被正常。server端不會導致連接abort,除非客戶端/服務器端發生了網絡問題。但這也是網絡導致的,而不是server端的問題。網絡問題可以借助工具來查看,比如:tcpdump,netstat -s
回到問題的本身,先看看mysql的參數設置:
mysql> show variables like ‘%timeout%‘; +-----------------------------+----------+ | Variable_name | Value | +-----------------------------+----------+ | connect_timeout | 10 | | interactive_timeout | 1800 | | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 60 | | wait_timeout | 1800 | +-----------------------------+----------+ mysql> show global variables like ‘%log_warning%‘; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_warnings | 2 | +---------------+-------+ 1 row in set (0.00 sec) mysql>
如果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)
如果不想在日誌中記錄這些信息,可以修改一下log_waring的值:
mysql>set @@global log_warning=1;
Aborted connection 1055898 to db: 'xxx' user: 'yyy' host: 'xxx.xxx.xxx.xxx' (Got timeout reading communication packets)