seconds_behind_master计算方式

总是被问这个问题,不是准确值,之前看过记不清楚怎么计算的了,还是看下源码吧。。。

在函数show_slave_status_send_data中
看下伪代码
/*
     The pseudo code to compute Seconds_Behind_Master:
     if (SQL thread is running)
     {
       if (SQL thread processed all the available relay log)
       {
         if (IO thread is running)
            print 0;
         else
            print NULL;
       }
        else
          compute Seconds_Behind_Master;
      }
      else
       print NULL;
  */
代码中的计算方式
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)
        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));
    }
  }
  
查看Master_info的信息,有如下的描述:
 clock_diff_with_master is computed when the I/O thread starts; for this the
     I/O thread does a SELECT UNIX_TIMESTAMP() on the master.
"how late the slave is compared to the master" is computed like this:
     clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master
     

首先是只要认为sql线程应用完全部的relay log就认为是0了,本身这个方式就不是精确的,在传输或sql应用的时候,主库上一直有事务,肯定是有延时的,那么如果传输慢或有问题,也是0了。

参考了http://mysql.taobao.org/monthly/2016/03/09/
clock_diff_with_master io线程启动时会向主库发送sql语句“SELECT UNIX_TIMESTAMP()”,获取主库当前时间,然而用备库当前时间减去此时间或者主备时间差值即为clock_diff_with_master。这里如果有用户中途修改了主库系统时间或修改了timestamp变量,那么计算出备库延迟时间就是不准确的。

last_master_timestamp 表示主库执行binlog事件的时间。此时间在并行复制和非并行复制时的计算方法是不同的

看到是用当前时间减去last_master_timestamp这个值在减去时间差,last_master_timestamp这个是主库的binlog事件时间,那么在导入备份后,启动从库的时候,如果备份文件很大,在导入完启动复制的时候,所以我们会看到很大的延时出现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值