網絡閃段致slave 出錯分析


告警信息

    check_ins_slave_io_running (err_cnt:1)critical-  slaveio not run on ins:3014,3051,3060,3079,3097,3104,3106,3107,3108,3116,3119,3123,3170,3150,3151
         

復制錯誤

    錯誤1:

     Last_IO_Errno: 1159 (ER_NET_READ_INTERRUPTED)

     Last_IO_Error: The slave I/O thread stops because a fatal error is encountered when it try to get the value of SERVER_ID variable from master. Error: 

     錯誤2:     

    Last_IO_Errno: 1593 (ER_SLAVE_FATAL_ERROR)

    Last_IO_Error: The slave I/O thread stops because SET @master_heartbeat_period on master failed. Error: 

 

分析

 1 首先從告警信息,同一主機出現大量實例的復制錯誤。首先可以排出是mysql問題。應該是外部環境導致,例如網絡,硬件故障等。

 2 錯誤1159即ER_NET_READ_INTERRUPTED網絡中斷,由此可以推斷是網絡問題導致

 3 從錯誤信息中,Last_IO_Error: The slave I/O thread stops because a fatal error is encountered when it try to get the value of SERVER_ID variable from master。定位源碼可看到,IO thread每次啟動io_thread從主庫拉binlog是都有以下邏輯,(handle_slave_io-> get_master_version_and_clock)檢查serverid是否重復,時間鍾,時區,字符集,設置master heartbeat等. 此錯誤是在檢查serverid時發生網路中斷所致。

  類似的錯誤還有:

   Get master TIME_ZONE failed with error:xxx

 

處理方法

    stop slave;start slave; 即可恢復 

 

附:

http://dev.mysql.com/doc/refman/5.5/en/change-master-to.html change master 時可以指定MASTER_CONNECT_RETRY表示連接斷開重試間隔時間,master-retry-count是mysqld啟動命令行參數表示連接重試次數 。http://dev.mysql.com/doc/refman/5.5/en/replication-options-slave.html#option_mysqld_master-retry-count.

 

為什么這個錯誤沒有重連呢,原因是這個錯誤出現后,用戶退出了io_thread線程。重連是io_thread發出的,因此自然就不會重連了。看如下日志:

 

140814  8:40:05 [Note] Event Scheduler: scheduler thread started with id 93413

140814  8:40:49 [ERROR] Slave I/O: The slave I/O thread stops because SET @master_heartbeat_period on master failed. Error: , Error_code: 1593

140814  8:40:49 [Note] Slave I/O thread exiting, read up to log 'mysql-bin.000012', position 107

  

問題:

is_network_error函數判斷沒有把ER_NET_READ_INTERRUPTED加入到網絡錯誤中。

bool is_network_error(uint errorno)

  if (errorno == CR_CONNECTION_ERROR || 

      errorno == CR_CONN_HOST_ERROR ||

      errorno == CR_SERVER_GONE_ERROR ||

      errorno == CR_SERVER_LOST ||

      errorno == ER_CON_COUNT_ERROR ||

      errorno == ER_SERVER_SHUTDOWN)

    return TRUE;

 

  return FALSE;   

}

這里如果修改認為ER_NET_READ_INTERRUPTED為網絡錯誤,就不會退出io_thread線程,並且會重連。

不過如果這樣重連會導致用會忽略get_master_version_and_clock里面的后續檢查,這個應該選擇退出io_thread線程,而不重連的原因吧。

 


免責聲明!

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



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