MySQL的Seconds_Behind_Master 是如何计算的

Seconds_Behind_Master 如何计算

以下是源码中关于延迟时间计算方法的注释说明

# 位于rpl_mi.h中定义clock_diff_with_master附近(翻阅了5.6.34和5.7.22 两个版本,对于复制延迟的计算公式两者一致)
# 从源码注释上来看,复制延迟的计算公式为 clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master
# 该公式的含义为:从库的当前系统(主机)时间 - 从库 SQL 线程正在执行的event的时间戳 - 主从库的系统(主机)之间的时间差
/*The difference in seconds between the clock of the master and the clock ofthe slave (second - first). It must be signed as it may be <0 or >0.clock_diff_with_master is computed when the I/O thread starts; for this theI/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*/
# clock_diff_with_master 值为主从服务器的主机时间差,该值只在I/O线程启动时计算一次,后续每次计算Seconds_Behind_Master字段值时,是直接复用这个计算结果,每次重启I/O线程时该值会重新计算long clock_diff_with_master;  # master_row[0] 为从库在主库上执行SELECT UNIX_TIMESTAMP()的操作,clock_diff_with_master为主从库主机的时间差计算结果mi->clock_diff_with_master=(long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));# 从rpl_slave.cc 文件中启动 I/O 线程时可以看出:start_slave_thread-> # 启动start slavehandle_slave_io-> # 启动start io threadget_master_version_and_clock # 获取当前slave和主机之间的时间差(clock_diff_with_master)以下是源码中关于Seconds_Behind_Master 计算结果的一些判定值/*The pseudo code to compute Seconds_Behind_Master:  # 阐明这是一段注释关于如何计算Seconds_Behind_Master的伪代码if (SQL thread is running)  # 如果SQL线程正在运行,则进入这个if判断内,假设这里标记为if one{if (SQL thread processed all the available relay log)  # 如果SQL线程应用完成了所有可用的relay log,则进入这个if判断内,假设这里标记为if two{if (IO thread is running)  # 如果I/O线程正在运行,则进入这个if判断内,假设这里标记为if threeprint 0;  # 如果if one/two/three三个条件都为真,则延迟值判定为0elseprint NULL;  # 如果if one/two为真,if three为假,则延迟值判定为NULL}elsecompute Seconds_Behind_Master;  # 如果if one为真,if two为假,则执行公式计算延迟值}elseprint NULL;  # 如果if one为假,则延迟值判定为NULL
*/if (mi->rli->slave_running)
{/*Check if SQL thread is at the end of relay logChecking should be done using two conditionscondition1: compare the log positions andcondition2: 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);elseprotocol->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 possiblereasons 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, andthat 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) whenthe slave's timestamp is read it is at the very beginning of second2. Then the recorded value for master is 1 and the recorded value forslave is 2. At SHOW SLAVE STATUS time, assume that the differencebetween 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 aspecial marker to say "consider we have caught up".*/protocol->store((longlong)(mi->rli->last_master_timestamp ?max(0L, time_diff) : 0));  # time_diff这里其实就是最终计算的Seconds_Behind_Master 值,如果为负数,则直接归零}
}

从源码注释上来看,复制延迟的计算公式为

clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master

该公式的含义为:从库的当前系统(主机)时间 - 从库 SQL 线程正在执行的event的时间戳 - 主从库的系统(主机)之间的时间差

clock_diff_with_master 值为主从服务器的主机时间差,该值只在I/O线程启动时计算一次,后续每次计算Seconds_Behind_Master字段值时,是直接复用这个计算结果,每次重启I/O线程时该值会重新计算

  long time_diff= ((long)(time(0) - mi->rli->last_master_timestamp)- mi->clock_diff_with_master);

这行代码计算了一个名为 time_diff 的长整型变量,其值是当前时间(通过 time(0) 获取)与主实例上最后一个事件的时间戳(mi->rli->last_master_timestamp)之间的差异减去主从实例之间的时钟差异(mi->clock_diff_with_master)。这个 time_diff 的值表示当前时间与主实例最后一个事件的时间戳之间的秒数差异,减去主从实例之间的时钟差异。

显示的值分别代表什么

显示NULL

(1)当从库没有任何需要处理的更新时,如果I/O和SQL线程状态都为Yes,则此字段显示为0,如果有任意一个线程状态不为Yes,则此字段显示为NULL

(2)如果从库的SQL线程没运行、SQL线程正在运行且已经消费完了所有的relay log且I/O线程没有运行,则该字段显示为NULL

(3)如果I/O线程已经停止,但还存在着relay log未重放完成时,仍然会显示出复制延迟时间,直到所有relay log被重放完成之后,显示为NULL

显示0

(1)如果SQL线程和I/O线程都运行着,但是处于空闲状态(SQL线程已经重放完了I/O线程产生的

relay log),则该字段显示为0

(2)当从库没有任何需要处理的更新时,如果I/O和SQL线程状态都为Yes,则此字段显示为0

显示数值

代表延迟的数值

clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master

这种计算方式的局限性

网络延迟的问题

实际上,这个字段是度量从库SQL线程和I/O线程之间的时间差,单位为秒,如果主备之间的网络非常快,那么从库的I/O线程读取的主库binlog会与主库中最新的binlog非常接近,所以这样计算得来得值就可以作为主备之间的数据延迟时间,但是如果主备之间的网络非常慢,可能导致从库SQL线程正在重放的主库binlog 非常接近从库I/O线程读取的主库binlog,而I/O线程因为网络慢的原因可能读取的主库binlog远远落后于主库最新的binlog,此时,这么计算得来的值是不可靠的,尽管这个时候有可能该字段显示为0,但实际上可能从库已经落后于主库非常多了。所以,对于网络比较慢的情况,该值并不可靠。

如何解决网络问题带来的误判

复制实例的SQL线程可能经常追赶读取速度较慢的复制实例的I/O线程,因此Seconds_Behind_Master经常显示为0,即使I/O线程相对于主实例是延迟的。换句话说,该列仅在快速网络中才有用。

那如何判断是否是网络的问题呢,这就取决于是IO线程的延迟还是SQL线程延迟的问题。

如何判断是否IO线程还是SQL线程的延迟

通过如下两对值进行比对

第一对:( File , Position ) & ( Master_Log_File , Read_Master_Log_Pos )

这里面,

  • ( File , Position ) 记录了主库 binlog 的位置。
  • ( Master_Log_File , Read_Master_Log_Pos ) 记录了 IO 线程当前正在接收的二进制日志事件在主库 binlog 中的位置。

如果 ( File , Position ) 大于 ( Master_Log_File , Read_Master_Log_Pos ) ,则意味着 IO 线程存在延迟。

第二对:( Master_Log_File , Read_Master_Log_Pos ) & ( Relay_Master_Log_File , Exec_Master_Log_Pos )

这里面,( Relay_Master_Log_File, Exec_Master_Log_Pos ) 记录了 SQL 线程当前正在重放的二进制日志事件在主库 binlog 的位置。

如果 ( Relay_Master_Log_File, Exec_Master_Log_Pos ) < ( Master_Log_File, Read_Master_Log_Pos ) ,则意味着 SQL 线程存在延迟。

主机时间可修改

如果主库与从库的server自身的时间不一致,那么,只要从库复制线程启动之后,没有做过任何时间变更,那么这个字段的值也可以正常计算,但是如果修改了server的时间,则可能导致时钟偏移,从而导致这个计算值不可靠

如何解决主机时间带来的误判

主机上执行date命令查看当前时间

主机命令行执行  
date登录数据库执行
select now(),unix_timestamp(),from_unixtime(unix_timestamp());确保两个查询的时间符合当前的时间值

如果系统时间不符合当前时间,则修改时间为当前正确时间,再重启复制线程。

前面提到过clock_diff_with_master 值为主从服务器的主机时间差,该值只在I/O线程启动时计算一次,后续每次计算Seconds_Behind_Master字段值时,是直接复用这个计算结果,每次重启I/O线程时该值会重新计算。因此不用担心主从的主机时间完全一致。只需要确保与当前实际时间没有太大误差即可,重启复制线程会覆盖clock_diff_with_master的值。

大事务的情况

当SQL线程重放大事务时,SQL线程的时间戳更新相当于被暂停了(因为一个大事务的event在重放时需要很长时间才能完成,虽然这个大事务也可能会有很多event,但是这些event的时间戳可能全都相同),此时,根据计算公式可以得出,无论主库是否有新的数据写入,从库复制延迟仍然会持续增大(也就是说此时的复制延迟值是不可靠的)。所以就会出现主库停止写入之后,从库复制延迟逐渐增大到某个最高值之后突然变为0的情况。

多线程复制下的波动

多线程复制,则此值是基于Exec_Master_Log_Pos点的event时间戳来计算的,因此可能不会反映从库最近提交的事务的位置。

从库不是read_only

如果从库上通过客户端连接进入并直接更新数据,这可能导致该字段的值随机波动,因为有时候event来源于主库,有时候来源于从库直接更新产生的event,而这个字段的值会受到直接更新产生的event的影响。

总结

  1. 对于主从库主机时间不一致的情况,在I/O线程第一次启动时,会计算主从之间的主机时间差,在后续计算复制延迟时,会把这个时间差减掉,这样就可以保证正确获取到复制延迟时间,但是该时间差只在I/O线程启动时才会进行计算,所以,当I/O线程启动之后修改了主从库的主机时间,则根据计算公式,会导致复制延迟时间不可靠,但是当I/O线程重启之后就可以恢复(因为I/O线程重启时,主从之间的时间差重新计算了)

  2. 在计算复制延迟时(执行 SHOW SLAVE STATUS语句时会进行计算),对Seconds_Behind_Master计算结果做一些判定(上文源码介绍部分的伪代码注释里有讲解过,这里再啰嗦一下):

    如果 I/O 和 SQL线程同时为 Yes,且SQL线程没有做任何事情(没有需要被执行的event),此时直接判定复制延迟结果为0,不会走公式计算延迟时间,否则会走公式计算延迟时间(所以,在该前置条件下不会出现当主库没有写任何binlog event时,从库延迟不断加大的情况)

    如果 SQL线程为Yes,且还存在着 I/O 线程已经读取的relay log未应用完成的,则会走公式计算延迟时间,而不管 I/O线程是否正在运行,但当SQL线程重放完成了所有relay log时,如果 I/O线程不为Yes,直接判定复制延迟结果为NULL

    任何时候,如果SQL线程不为Yes,直接判定复制延迟结果为NULL。当计算出的复制延迟为负数时,直接归零

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/799666.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

直通车人群和引力魔方人群的区别

1&#xff09;直通车的人群&#xff0c;他和引力魔方的人群看起来一样&#xff0c;但是作用不一样&#xff0c;直通车广告是通过关键词筛选流量的&#xff0c;人群只是起到溢价作用&#xff0c;引力魔方人群是筛选作用出价作用&#xff1b; 2&#xff09;直通车的人群&#xf…

python之列表操作

1、创建列表 代码示例&#xff1a; i [1, 2, 34, 4] o list((1, 2, 3, 4, 5, 6)) 分别创建了两个数组&#xff0c;这两种格式都能创建数组 2、关于数组的操作 1、添加元素 1、append&#xff08;&#xff09; append方法主要是添加一个元素 代码示例如下&#xff1a;…

深度学习理论基础(七)Transformer编码器和解码器

学习目录&#xff1a; 深度学习理论基础&#xff08;一&#xff09;Python及Torch基础篇 深度学习理论基础&#xff08;二&#xff09;深度神经网络DNN 深度学习理论基础&#xff08;三&#xff09;封装数据集及手写数字识别 深度学习理论基础&#xff08;四&#xff09;Parse…

手机软件何时统一--桥接模式

1.1 凭什么你的游戏我不能玩 2007年苹果手机尚未出世&#xff0c;机操作系统多种多样&#xff08;黑莓、塞班、Tizen等&#xff09;&#xff0c;互相封闭。而如今&#xff0c;存世的手机操作系统只剩下苹果OS和安卓&#xff0c;鸿蒙正在稳步进场。 1.2 紧耦合的程序演化 手机…

vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户

1.后端返回的json数据结构为&#xff1a; {"message":"下载失败&#xff0c;下载文件不存在&#xff0c;请联系管理员处理&#xff01;","code":500} 2.vue 请求后台接口返回的 Blob数据 3.问题出现的原因是&#xff0c;正常其他数据列表接口&…

[C++][算法基础]堆排序(堆)

输入一个长度为 n 的整数数列&#xff0c;从小到大输出前 m 小的数。 输入格式 第一行包含整数 n 和 m。 第二行包含 n 个整数&#xff0c;表示整数数列。 输出格式 共一行&#xff0c;包含 m 个整数&#xff0c;表示整数数列中前 m 小的数。 数据范围 1≤m≤n≤&#x…

第4章 Redis,一站式高性能存储方案,笔记问题

点赞具体要实现功能有哪些&#xff1f; 可以点赞的地方&#xff1a;对帖子点赞&#xff0c;对评论点赞点一次是点赞&#xff0c;再点一次是取消赞统计点赞的数量&#xff08;计数&#xff0c;string&#xff09;&#xff0c;帖子被点赞的数量&#xff0c;某个用户被点赞的数量…

【数据结构】考研真题攻克与重点知识点剖析 - 第 5 篇:树与二叉树

&#xff08;考研真题待更新&#xff09; 欢迎订阅专栏&#xff1a;408直通车 请注意&#xff0c;本文中的部分内容来自网络搜集和个人实践&#xff0c;如有任何错误&#xff0c;请随时向我们提出批评和指正。本文仅供学习和交流使用&#xff0c;不涉及任何商业目的。如果因本…

2024免费Mac电脑用户的系统清理和优化软件CleanMyMac

作为产品营销专家&#xff0c;对于各类产品的特性与优势有着深入的了解。CleanMyMac是一款针对Mac电脑用户的系统清理和优化软件&#xff0c;旨在帮助用户轻松管理、优化和保护Mac电脑。以下是关于CleanMyMac的详细介绍&#xff1a; CleanMyMac X2024全新版下载如下: https://…

阿里云乱扣费故障,技术堪忧

2024年4月3日&#xff0c;距离2023年11月的故障没有多久&#xff0c;阿里云又出现乱扣费故障&#xff0c;导致账号欠费3000多&#xff0c;oss&#xff0c;块存储&#xff0c;cdn等所有后付费服务停止工作&#xff0c;不知道这个故障能算什么级别的。 凌晨1点多&#xff0c;收到…

用Vue全家桶手工搓了一个类似抖音短视频的软件,全开源

用Vue全家桶手工搓了一个类似抖音短视频的软件&#xff0c;全开源 软件简介 用Vue全家桶手工搓了一个高仿抖音&#xff0c;全开源 PC浏览器请用手机模式访问。先按F12调出控制台&#xff0c;再按CtrlShiftM切换到手机模式&#xff0c;手机请用Via浏览器或者Chrome浏览器预览。…

Octopus V2:设备端super agent的高级语言模型

论文&#xff1a;Octopus v2: On-device language model for super agent论文地址&#xff1a;https://arxiv.org/abs/2404.01744模型主页&#xff1a;https://huggingface.co/NexaAIDev/Octopus-v2 Octopus-V2-2B Octopus-V2-2B 是一款具有20亿参数的开源先进语言模型&#…

性能分析-docker知识

docker的相关概念 docker是一个做系统虚拟化的软件&#xff0c;跟vmware类似&#xff0c;虚拟出来的也是操作系统。我们现在在企业中&#xff0c; 使用docker虚拟出来的系统&#xff0c;大多都是linux系统。 docker镜像image&#xff1a;就是虚拟一个docker容器需要的操作系统…

Ubuntu 20.04.06 PCL C++学习记录(十八)

[TOC]PCL中点云分割模块的学习 学习背景 参考书籍&#xff1a;《点云库PCL从入门到精通》以及官方代码PCL官方代码链接,&#xff0c;PCL版本为1.10.0&#xff0c;CMake版本为3.16 学习内容 PCL中实现欧式聚类提取。在点云处理中,聚类是一种常见的任务,它将点云数据划分为多…

基于单片机三相温度测量控制系统设计

**单片机设计介绍&#xff0c;基于单片机三相温度测量控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机三相温度测量控制系统设计概要主要包括系统组成、温度测量原理、控制逻辑、软件设计以及测试与验证等…

2.k8s架构

目录 k8s集群架构 控制平面 kube-apiserver kube-scheduler etcd kube-controller-manager node 组件 kubelet kube-proxy 容器运行时&#xff08;Container Runtime&#xff09; cloud-controller-manager 相关概念 k8s集群架构 一个Kubernetes集群至少包含一个控制…

PPT 操作

版式 PPT中&#xff0c;巧妙使用母版&#xff0c;可以提高效率。 双击母版&#xff0c;选择其中一个版式&#xff0c;插入装饰符号。 然后选择关闭。 这个时候&#xff0c;在该版式下的所有页面&#xff0c;就会出现新加入的符号。不在该版式下的页面&#xff0c;不会出现新加…

八股面试——数据库——索引

索引的概念 B树的概念&#xff1a; 索引的作用 聚簇索引与非聚簇索引 聚簇索引就是主键值&#xff0c;在B树上&#xff0c;通过主键大小&#xff08;数据在B树叶子节点按主键顺序排序&#xff09;寻找对应的叶子节点&#xff0c;叶子节点保存的一整条记录。 非聚簇索引&#x…

Mysql底层原理一:事务

因为数据库操作也是并发操作&#xff0c;多个客户端在操作的时候&#xff0c;可能会存在很多问题 1. 一些问题 ● 脏写&#xff08;人家还没有提交&#xff0c;我可以改别人的数据&#xff09;&#xff0c;这个在数据库不存在&#xff0c;已经通过锁解决了 ● 脏读&#xff0…

ctfshow web入门 命令执行 web53--web77

web53 日常查看文件 怎么回事不让我看十八 弄了半天发现并不是很对劲&#xff0c;原来我发现他会先回显我输入的命令再进行命令的回显 ?cnl${IFS}flag.php||web54 绕过了很多东西 基本上没有什么命令可以用了但是 grep和?通配符还可以用 ?cgrep${IFS}ctfshow${IFS}???…