Mysql主從同步延遲與系統時間的關係

Mysql主從同步延遲與系統時間的關係

ysql主從同步延遲受到多種因素影響, 比如大事務, 從庫查詢壓力, 網路延遲等; 這些比較常見; 但還受到主從機器系統時鐘差的影響,這一點可能容易被忽視。
上週, 就遇到了這樣的情況, 主庫的系統時間由於某種原因落後於從庫幾十秒, 結果頻繁的出現大的主從延遲同步 ,查了N久業務方面的問題,都找不出原因; 在和同事的交流中,發現大家對參數Seconds_Behind_Master的理解有點補一樣,基本有兩種理解:

一種理解是來源於 Mysql手冊上的描述,大體意思是這個時間是從庫SQL線程處理的最近的日誌事件的時間戳減去從庫IO線程處理的最近一條日誌記錄的時間戳得到的, 可以簡單理解爲從庫SQL線程與IO線程所處理的最近的日誌事件的時間戳差;這個計算方式給人的感覺不是在計算主從延遲,而是在計算從庫上兩個線程的處理的日誌的時差。
另一種理解來源於《High Performace Mysql》上的的描述,大體意思這個參數反映的結果是當前系統時間減去從庫IO線程所處理的最近一條日誌記錄的時間戳; 但這個說法有一個明顯的不太讓人信服的地方,就是如果機器的系統時間相差比較大怎麼辦? 顯然, 如果系統時間相差比較大的話, 以這樣的方式計算主從延遲毫無意義。

在有分歧的情況下, 去查看了一下Mysql的源代碼, 結果發現手冊上的描述居然不那麼準確, 代碼大致如下:
......if ((mi->slave_running == MYSQL_SLAVE_RUN_CONNECT) &&mi->rli.slave_running){
long time_diff= ((long)(time(0) - mi->rli.last_master_timestamp) - mi->clock_diff_with_master);
protocol->store((longlong)(mi->rli.last_master_timestamp ? max(0, time_diff) : 0));
......}else{
protocol->store_null();
}
從代碼看, 如果從庫IO線程到主庫的連接有問題或者SQL線程沒有在運行, Seconds_Behind_Master直接返回NULL; 否則的話, 用從庫當前系統時間減去IO線程處理的最近的事件的時間戳;代碼裏用mi->clock_diff_with_master來排除系統時間差對計算的影響, 那這個值又是怎麼計算來的呢? 繼續看代碼:

......if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&(master_res= mysql_store_result(mysql)) &&(master_row= mysql_fetch_row(master_res))){ mi->clock_diff_with_master = (long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));}else if (!check_io_slave_killed(mi->io_thd, mi, NULL)){ mi->clock_diff_with_master= 0; ......}

原來這個值是通過在主庫上執行SELECT UNIX_TIMESTAMP()來取得主庫的系統時間, 然後去減從庫的當前系統時間。

原來系統時間差還真的對主從同步延遲參數Seconds_Behind_Master有影響。
轉載:http://hi.baidu.com/zhencaishu/blog/item/355f8c1078d537f5c2ce79c2.html
在今天的一次主從部署中,發現主從庫所在系統時間差別較大時(差別20天左右),同步的性能也非常差。但沒有找到證據,暫且如此懷疑,以後留意
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章