Seconds_Behind_Master不准确问题
Seconds_Behind_Mas析ter解
1. Seconds_Behind_Master说明:
通过show slave status查看到的Seconds_Behind_Master,从字面上来看,他是slave落后master的秒数,一般情况下,也确实这样,我们可以通过Seconds_Behind_Master数字查看slave是否落后于master,但是在一些环境中,他确会让我们产生幻觉。
在mysql官网中中,对Seconds_Behind_Master的有一句话阐述如下:
In essence, this field measures the time difference in seconds between the slave SQL thread and the slave I/O thread.
很清晰的表明,该值是SQL thread I/O thread.之间的差值。
2. Seconds_Behind_Master原理
Seconds_Behind_Master是通过比较sql_thread执行的event的timestamp和io_thread复制好的 event的timestamp(简写为ts)进行比较,而得到的这么一个差值。我们都知道的relay-log和主库的bin-log里面的内容完全一 样,在记录sql语句的同时会被记录上当时的ts,所以比较参考的值来自于binlog。
3. 导致Seconds_Behind_Master不准确的因素‘
a. 当在很快的网络连接情况下,I/O thread. 能很快的从master的binlog中同步sql到slave的relay-log里,这样,这个值就能基本确定的slave落后master的秒数
当网络环境特别糟糕的情况下,这个值确会让我们产生幻觉,I/O thread同步很慢,每次同步过来,SQL thread就能立即执行,这样,我们看到的Seconds_Behind_Master是0,而真正的,slave已经落后master很多很多。这时业务部门的同志们就会抱怨slave与master数据不对,而你看到的Seconds_Behind_Master确实为0,你就会非常的郁闷了。
其实这个时候,我们看下master,与slave就能很好的确定这期间的原因。
mysql> show master status\G
*************************** 1. row ***************************
File: ******-bin.001291
Position: 896711460
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.69.6.163
Master_User: replica
Master_Port: 3801
Connect_Retry: 60
Master_Log_File: *****-bin.001211
Read_Master_Log_Pos: 278633662
Relay_Log_File: *****-relay-bin.002323
Relay_Log_Pos: 161735853
Relay_Master_Log_File: *******-bin.001211
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 278633662
Relay_Log_Space: 161735853
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
b. 有很长一段时间没有数据提交,slave I/O thread time和slave SQL thread time都保持在旧值,比如A(但事实上master上的时间已经到A+I了),这个时候主库出现提交,slave I/O开始去和master同步binlog,slave I/O thread time更新到A+I,但是slave SQL thread time保持在A值,这时的seconds_behind_master=I,出现较大延迟,但其实是否出现延迟是不确定的
c.Mysql主从同步延迟受到多种因素影响, 比如大事务, 从库查询压力, 网路延迟等; 这些比较常见; 但还受到主从机器系统时钟差的影响,这一点可能容易被忽视。
d.总结:由此看来 我们分析Seconds_Behind_Master这个参数的时候应该结合主从之间binlog日志的文件名和具体的网络环境来看。当然在网络畅通的情况下我们可以直接通过这个参数来看出主从之间的延迟。不过总的来说seconds_behind_master受影响的因素很多不能保持准确。
4. 对于second_behind_master不准确的解决方案
mk-heartbeat,Maatkit万能工具包中的一个工具,被认为可以准确判断复制延时的方法。
mk-heartbeat的实现也是借助timestmp的比较实现的,它首先需要保证主从服务器必须要保持一致,通过与相同的一个NTP server同步时钟。它需要在主库上创建一个heartbeat的表,里面至少有id与ts两个字段,id为server_id,ts就是当前的时间戳 now(),该结构也会被复制到从库上,表建好以后,会在主库上以后台进程的模式去执行一行更新操作的命令,定期去向表中的插入数据,这个周期默认为1 秒,同时从库也会在后台执行一个监控命令,与主库保持一致的周期去比较,复制过来记录的ts值与主库上的同一条ts值,差值为0表示无延时,差值越大表示 延时的秒数越多。我们都知道复制是异步的ts不肯完全一致,所以该工具允许半秒的差距,在这之内的差异都可忽略认为无延时。这个工具就是通过实打实的复 制,巧妙的借用timestamp来检查延时