seconds_behind_master解密

今天aliyun同学反应有台机器seconds_behind_master为0,但实际有很多延迟。这个问题最终定位到是master大事务(row模式),没有pk引起(非网络不稳定)。在讨论过程中对seconds_behind_master计算有了些争论。

Sencods_behind_master到底怎么来的?存在两种计算方式
1、以前看文档记得:sql io thread复制好的event的timestamp减去sql thread执行的event的timestamp,所以当网络不好情况时,io thread该干的活没干完,sql thread已干完在slave上relay-log,就可以看到seconds_behind_master为0,但实际是因为master的binlog传不过来或传过来太慢。
2、slave的系统时间timestamp减去master最新event执行timestamp

两种方式分析:
1、通过计算,与实际不符。
在slave上,可以拿到io thread现在执行位置
Master_Log_File: mysql-bin.006107
Read_Master_Log_Pos: 187136961

Sql thread现在执行位置:
Relay_Log_File: mysqld-relay-bin.011583
Relay_Log_Pos: 9943902

对mysql-bin.006107的187136961解析,拿到时间点t1
对mysqld-relay-bin.011583的9943902解析,拿到时间点t2
seconds_behind_master = t1 – t2
实际得到时间差和seconds_behind_master相差很远。

2、计算得到时间差和seconds_behind_master相近

好吧,那我们再来看一下源码是怎么样计算的:^|^
long_time_diff就是seconds_behind_master

long time_diff= ((long)(time(0) - mi->rli.last_master_timestamp)- mi->clock_diff_with_master);
mi->clock_diff_with_master=(long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));

翻译如下:
seconds_behind_master=slave系统时间-master执行最新event的timestamp-(slave系统时间-master系统时间)

(slave系统时间-master执行最新event的timestamp):得到最新event到slave执行还要多久。
(slave系统时间-master系统时间):可能存在主备系统时间差别,所以计算seconds_behind_master要减去,但实际情况,slave和master系统时间基本一致,得到结果应该接近0

文档中这句误导很多人以第一种方式来计算seconds_behind_master
If the network is slow, this is not a good approximation; the slave SQL thread may quite often be caught up with the slow-reading slave I/O thread, so Seconds_Behind_Master often shows a value of 0


3 Responses to “seconds_behind_master解密”

  1. liky说道:

    slave 系统时间是个什么概念? 操作系统的date ?

  2. nan说道:

    看到这个文章,我有一个疑问,测试环境里,从机比主机慢8个小时,但是slave_behind_master=0,用这个公式计算,应该延时在8个小时左右了。

Post a Comment