Second_Behind_Master值
MySQL主从复制中的SBM
日常工作中,我们经常会和主从复制架构打交道,现在一般的公司线上很少出现单点实例的裸奔情况,因为单点实例极易出现故障,而在实例运行的过程中,我们很难做到一直对实例进行备份。主从复制完美的解决了上面这个问题,而在主从复制的过程中,最常见的事情就是需要统计从库落后主库的时间,一般情况下,我们是需要主从的落后时间越小越好,因为小的数字意味着从库的数据和主库的数据基本保持一致。当然,在某些情况下,我们也会人为的设置这个延迟时间,举例子就是在一些高危操作之前,我们害怕出现一些误操作,这个时候我们往往设置主从的延迟时间,这样即使主库上进行了误操作,例如删除了表,由于主从库之间延迟时间的存在,我们的从库可以避免这个问题,从而保障数据的安全性。
在MySQL中,衡量主从复制延迟时间最直接的参数就是show slave status中的seconds_behind_master值,这个值从理论上显示了主从服务器之间的延迟,事实上它并不总是准确的,我们今天就来看看它的取值和代表的意义。
首先我们需要知道这个值代表什么意思。我们看看官方手册上面给的值:
大体意思是有以下几个方面:
1、 当从库不断的处理更新的时候,这个值显示从库当前主机时间戳和来自主库的二进制中记录的时间戳之间的差异。
2、当从库没有任何需要处理的更新时,例如主库不写入时,如果I/O线程和SQL线程都是yes,则这个值是0,否则为NULL
3、如果主库和从库之间的网络非常快,那么从库的I/O线程读取的binlog会与主库中最新的binlog非常接近,这样计算出来的值会很小,单位为秒,基本上可以替代主从之间的数据延迟时间,这个时候是可靠的。
相反,
如果主库和从库之间的网络特别慢,则从库中的binlog时间可能远远落后于主库最新的binlog,但是二者的真实偏差时间非常小(由于网络慢导致看着偏差比较大),这个时候,这个字段的值是不可靠的。即使显示为0,但是也有可能是因为主库网络不好导致大量的binlog没有传过来,所以这个值在网络比较慢的时候不可靠。
4、如果主库与从库本身的时间不一致,那么只要从库的复制线程启动之后,没有做过任何的时间变更,那么这个字段的值也是可靠的,一旦修改了服务器的时间,那么这个值就变的不可靠了。
5、如果从库的SQL线程没有运行,则该字段显示为NULL;
如果从库的SQL线程已经消费完了relay log而I/O线程没有运行,则该字段显示为NULL;
如果I/O线程已经停止,但是relay log还没有重放完成的时候,仍旧会显示出复制时间。直到relay log被消费完,显示为NULL;
如果SQL线程和I/O线程都运行着,但是处于空闲状态,则该字段为0;
6、正常情况下,主库和从库中的binlog event值都来自于主库。如果在单线程复制的时候,我们在从库上做了一些操作,则有可能导致这个值产生一些波动。因为有时候event的值来自于主库,有时候来自于从库。如果是多线程复制,则这个值是基于Exec_Master_Log_Pos的enent时间戳来计算的。
上面是官方文档中的说明吗,我从一些研究MySQL源码的文章中得到了下面这样的计算公式:
* clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master
也就是"从库的当前系统(主机)时间 - 从库 SQL 线程正在执行的event的时间戳 - 主从库的系统(主机)之间的时间差",其中最后一项diff的值,就是主库和从库的主机时差。这个时差在I/O线程启动的时候只计算一次,如果此时更改了系统时间,那么无疑会导致复制的SBM值不可靠。
当Seconds_Behind_Master计算结果为负数的时候,直接归零
通过上面的描述,我们可以得到以下的结论:
1. 如果 I/O 和 SQL线程同时为 Yes,且SQL线程没有做任何事情(没有需要被执行的event),此时直接判定复制延迟结果为0,不会走公式计算延迟时间,否则会走公式计算延迟时间
2. 如果 SQL线程为Yes,且还存在着 I/O 线程已经读取的relay log未应用完成的,则会走公式计算延迟时间,而不管 I/O线程是否正在运行,但当SQL线程重放完成了所有relay log时,如果 I/O线程不为Yes,直接判定复制延迟结果为NULL
3. 任何时候,如果SQL线程不为Yes,直接判定复制延迟结果为NULL。当计算出的复制延迟为负数时,直接归0
4. 当SQL线程重放大事务时,SQL线程的时间戳更新相当于被暂停了(因为一个大事务的event在重放时需要很长时间才能完成,虽然这个大事务也可能会有很多event,但是这些event的时间戳可能全都相同),此时,根据计算公式可以得出,无论主库是否有新的数据写入,从库复制延迟仍然会持续增大,会出现主库停止写入之后,从库复制延迟逐渐增大到某个最高值之后突然变为0的情况
5.根据公式计算,如果主库持续不断产生二进制日志(持续不断有数据变更),则复制延迟的计算结果不会出现误差(或者说误差可以忽略不计,因为从库的系统时钟是正常向后推进的,除非主从库的系统时间被改动了),如果在慢速网络中主库断断续续写入数据,甚至主库突然停止任何数据写入,之后实际上主库并没有新的数据写入(也就不会有新的binlog event时间戳产生),但是由于计算公式中并不感知这个变化,所以随着从库的系统时钟继续向前推进,就会导致在追赶上主库的数据之前,计算出的延迟时间值越来越大。