1.以前一直對這個參數很模糊,今天閒下心來看源碼文件 sql/rpl_slave.cc (MySQL 5.6.16)
if (mi->rli->slave_running) { /* Check if SQL thread is at the end of relay log Checking should be done using two conditions condition1: compare the log positions and condition2: compare the file names (to handle rotation case) */ if ((mi->get_master_log_pos() == mi->rli->get_group_master_log_pos()) && (!strcmp(mi->get_master_log_name(), mi->rli->get_group_master_log_name()))) { if (mi->slave_running == MYSQL_SLAVE_RUN_CONNECT) #IO SQL都處於runing且空閒時刻 time_diff=0 protocol->store(0LL); else protocol->store_null(); } else { long time_diff= ((long)(time(0) - mi->rli->last_master_timestamp) #計算公式 - mi->clock_diff_with_master); /* Apparently on some systems time_diff can be <0. Here are possible reasons related to MySQL: - the master is itself a slave of another master whose time is ahead. - somebody used an explicit SET TIMESTAMP on the master. Possible reason related to granularity-to-second of time functions (nothing to do with MySQL), which can explain a value of -1: assume the master's and slave's time are perfectly synchronized, and that at slave's connection time, when the master's timestamp is read, it is at the very end of second 1, and (a very short time later) when the slave's timestamp is read it is at the very beginning of second 2. Then the recorded value for master is 1 and the recorded value for slave is 2. At SHOW SLAVE STATUS time, assume that the difference between timestamp of slave and rli->last_master_timestamp is 0 (i.e. they are in the same second), then we get 0-(2-1)=-1 as a result. This confuses users, so we don't go below 0: hence the max(). last_master_timestamp == 0 (an "impossible" timestamp 1970) is a special marker to say "consider we have caught up". */ protocol->store((longlong)(mi->rli->last_master_timestamp ? max(0L, time_diff) : 0)); #diff_tiime< 0 當做0處理。 } } else { protocol->store_null(); #IO或SQL線程時NO,或者同時爲NO,Seconds_Behind_Master爲NULL }
總結:
1.從上面的源碼部分看出,Seconds_Behind_Master=當前slave 系統時間減去sql_thread最近接受到的binlog的timestamp,然後再減去master和slave的系統時間差。當值< 0 ,處理成0了。
從上面也可以看出,((long)(time(0) - mi->rli->last_master_timestamp) #計算公式
- mi->clock_diff_with_master);
可以分析出 延時 跟master和slave的時區無關。M +7 S +8 M在10點執行 diff_time=(11-10)- (11-10) = 0 ,只要S 沒有延時。
2.IO或SQL線程時NO,或者同時爲NO,Seconds_Behind_Master爲NULL,這也是在複製中斷時看到爲NULL。
很好奇就算可以出現負數的情況,但是已經都處理成0了。
3.* 出現負數的情況:
1.人爲的set master 的系統時間小於 slave
2. A--->B-->C :計算C 延時binlog 的時間取的是A的時間,有在主從之外的節點的時間值加入計算,有可能出現負值。