MySQL5.6 大量SQL語句處於Writing to net狀態的案例分析


【問題現象】

開發同事反饋有應用在21:00-22:00之間出現大量超時報錯。

 

【問題分析】

1、 從DB服務器慢查詢指標來看,18:00后有大量的慢查詢,累計產生了約9000條慢查詢

 

 

2、 測試直接執行慢查詢SQL語句,並沒有發現性能問題

 

3、當時DBA同事在排障現場看到了線程執行時等待Writing to net。

之前我們碰到過大量Writing to net等待的情況,通常是DB服務器網卡流量打滿導致。但這次從DB服務器網卡流量上看,並沒有打滿,而且比較平穩。

從QPS和threads_running指標來看,並發不是很高,相對平穩。

 

4、 Writing to net狀態究竟代表了什么

Writing to net

The server is writing a packet to the network.

這里先簡單描述下SQL語句查詢的流程:

<1>掃描一行,寫到net_buffer,這里net buffer 是按照net_buffer_length 初始化, 但可以動態增長到max_allowed_packet配置值

<2>繼續獲取滿足條件的行,直到寫滿net_buffer,然后調用網絡接口發送出去

<3>客戶端接收網絡包完成,清空net_buffer

<4>重復上面1到3的步驟

<5>如果發送未完成,表示socket send buffer寫滿,這時會進入等待狀態,顯示Writing to net,直到socket send buffer重新可寫,再繼續發送

 

下面是MySQL5.6.21的代碼片段:

 

static const char *thread_state_info(THD *tmp)

{

#ifndef EMBEDDED_LIBRARY

  if (tmp->net.reading_or_writing)

  {

    if (tmp->net.reading_or_writing == 2)

      return "Writing to net";

    else if (tmp->get_command() == COM_SLEEP)

      return "";

    else

      return "Reading from net";

  }

  else

#endif

  {

    if (tmp->proc_info)

      return tmp->proc_info;

    else if (tmp->mysys_var && tmp->mysys_var->current_cond)

      return "Waiting on cond";

    else

      return NULL;

  }

}

 

由於MySQL是邊掃描邊發送數據的,當客戶端接收慢時,就會阻塞整個查詢進程,導致執行變慢。

 

注意MySQL5.7.8以后,狀態發生了變化

Sending to client

The server is writing a packet to the client. This state is called Writing to net prior to MySQL 5.7.8.

 

5、 在網絡通信的鏈路上,DB端網絡沒有問題,需要繼續排查網絡通信緩存區瓶頸,以及客戶端的網絡或處理。

當時排障時,DBA嘗試調整放大了max_allowed_packet參數,但是效果不明顯。

從應用服務器的網絡指標,可以看出從中午12:35-00:00間,有大量套接字處於連接狀態establish。與DB端的慢查詢趨勢基本一致。

 

6、到這里基本可以定位問題是由於WEB客戶端接收處理DB端發送的網絡包比較慢,導致了SQL語句處於Writing to net狀態,執行很慢。

這里可能是WEB應用服務器異常,或WEB客戶端或宿主機的網絡問題。

 

7、后面聯系了相關同事,排查到這台WEB服務器對應的宿主機相關的交換機在這段時間有性能問題。

 

數據庫運維經驗分享&MySQL源碼學習漫漫路

 


免責聲明!

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



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