【MySQL源码】Seconds_Behind_Master是如何计算的

作为MySQL DBA,相信大家对参数  `Seconds_Behind_Master` 并不陌生,该字段的值可以通过 show  slave status\G的输出,表示主从延迟的时间,单位为秒。监控主从延迟一般取这个值就足够了。0 表示无延迟,理想状态该值不要超过1。如果业务场景中有写后读,而且读的是从库,那么就会对主从延迟要求非常高。

理解了该字段的含义,大家有没有探究过该值是如何计算的?相信大家都可以说出来 是从库的时间 减去 SQL_thread应用到的主库binlog event的时间戳。

今天从官方文档 和 MySQL源码 探寻正确的计算方法 

MySQL官方文档如何解释

原文

翻译

Seconds_Behind_Master

该字段表示复制实例相对于主实例的“延迟”:

  • 当复制实例正在处理更新时,该字段显复制实例上当前时间戳正在处理的事件在主实例上原始时间戳之间的差异。

  • 当复制实例上没有正在处理的事件时,该值为0。

基本上,该字段测量复制实例的SQL线程复制实例的I/O线程之间的秒数差异。如果主实例和复制实例之间的网络连接很快,复制实例的I/O线程非常接近主实例,因此该字段是复制实例的SQL线程相对于主实例的延迟的良好近似值。如果网络速度较慢,这就不是一个良好的近似值;复制实例的SQL线程可能经常追赶读取速度较慢的复制实例的I/O线程,因此Seconds_Behind_Master经常显示为0,即使I/O线程相对于主实例是延迟的。换句话说,该列仅在快速网络中才有用。

即使主实例和复制实例的时钟时间不同,只要在复制实例的I/O线程启动时计算的差异保持不变,此时间差异计算就有效。任何更改,包括NTP更新,都可能导致时钟偏差,使Seconds_Behind_Master的计算变得不太可靠。

在MySQL 5.7中,如果复制实例的SQL线程未运行,或者SQL线程已经消耗完中继日志并且复制实例的I/O线程未运行,该字段为NULL(未定义或未知)。 (在MySQL的早期版本中,如果复制实例的SQL线程或复制实例的I/O线程未运行或未连接到主实例,则该字段为NULL。)如果I/O线程正在运行但中继日志用尽,Seconds_Behind_Master设置为0。

Seconds_Behind_Master的值基于存储在事件中的时间戳,这些事件通过复制进行保留。这意味着如果主实例M1本身是主实例M0的复制实例,M1二进制日志中源自M0二进制日志的任何事件都具有M0该事件的时间戳。这使得MySQL能够成功地复制时间戳。然而,对于Seconds_Behind_Master而言,问题在于如果M1还直接从客户端接收更新,那么Seconds_Behind_Master的值会随机波动,因为M1的最后一个事件有时源自M0,有时是M1上的直接更新的结果。

在使用多线程复制时,您应该记住该值基于Exec_Master_Log_Pos,因此可能不反映最近提交的事务的位置。

官方文档的翻译也有两种计算方法 :

方法一:该字段显复制实例上当前时间戳正在处理的事件在主实例上原始时间戳之间的差异

方法二:该字段测量复制实例的SQL线程复制实例的I/O线程之间的秒数差异,前提主实例和复制实例之间的网络连接很快,复制实例的I/O线程非常接近主实例

源码中如何计算

在源码中全局搜索 Seconds_Behind_Master 关键字 ,排除测试文件,出现Seconds_Behind_Master关键字的文件也就几个。找到关于计算Seconds_Behind_Master 源码。

注释中也给出了 计算Seconds_Behind_Master 的伪代码 

  /*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;elseprint NULL;}elsecompute Seconds_Behind_Master;}elseprint NULL;*/

// 伪代码:计算 Seconds_Behind_Masterif (SQL 线程正在运行) {if (SQL 线程已处理所有可用的中继日志) {if (IO 线程正在运行) {输出 0;  // I/O 线程正在运行,但中继日志已用尽,因此 Seconds_Behind_Master 设置为 0。} else {输出 NULL;  // I/O 线程不在运行,因此 Seconds_Behind_Master 为 NULL。}} else {计算 Seconds_Behind_Master;  // 计算复制实例相对于主实例的延迟。}
} else {输出 NULL;  // SQL 线程不在运行,因此 Seconds_Behind_Master 为 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));}}else{protocol->store_null();}

具体计算方式 

      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 的值表示当前时间与主实例最后一个事件的时间戳之间的秒数差异,减去主从实例之间的时钟差异。

   clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master
 

  /*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*//*主时钟和从属时钟之间的差异(second - first)。它必须是有符号的,因为它可能 <0 或 >0。clock_diff_with_master 是在 I/O 线程启动时计算的;为此,I/O 线程在主实例上执行 SELECT UNIX_TIMESTAMP()。“从属相对于主实例的延迟”是这样计算的:clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master
*/

参考 

官方文档 Seconds_Behind_Master 解释

MySQL :: MySQL 5.7 Reference Manual :: 13.7.5.34 SHOW SLAVE STATUS Statement

MySQL 复制延迟 Seconds_Behind_Master 究竟是如何计算的 - 知乎

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

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

相关文章

【数据分享】1992-2019年中国水土保持防治能力数据集

土壤数据是在环境、农业、生态等相关研究中都非常常用的数据&#xff01;我们之前发表过一篇介绍土壤数据来源的文章&#xff08;可查看之前发布的文章获悉详情&#xff09;&#xff01; 水土保持防治能力是土壤的重要属性。本次我们给大家带来的是1992-2019年中国水土保持防治…

vue3 中组合键 command+Enter / shift+Enter / alt + Enter 实现换行,详细实现

vue3 中组合键实现换行 需求背景 有一个聊天室功能&#xff0c;采用输入框的形式&#xff0c;输入完毕使用Enter&#xff0c;可以直接进行发送。使用一些组合键 比如 commandEnter / shiftEnter / alt Enter … 可以实现换行操作。但现实的情况是&#xff0c;原生 Enter 天然…

uniapp安卓android离线打包本地打包整理

离线打包准备 下载Android studio 1.准备资源hbuilder 2.准备离线SDK 最新android平台SDK下载最新android平台SDK下载 3.离线打包key申请 4.直接导入HBuilder-Integrate-AS工程,直接运行simpleDemo项目即可 5.安装java 1.8 jdk-8u151-windows-x64 6.遇到这个报错报错Caus…

xshell无法连接linux,查询本机ip时出现<NO-CARRIER,BROADCAST,MULTICAST,UP>

在用xshell连接虚拟机VMware中的linux时&#xff0c;发现昨天还能连通的&#xff0c;今天连接不了了 我寻思应该是网卡配置出问题了&#xff0c;就去终端ip addr试了一下&#xff0c;果然发现问题&#xff0c;ip 查看网卡ens33就发现出现ens33:<NO-CARRIER,BROADCAST,MULTI…

SpringSecurity认证登录成功后获取角色菜单

目录 前言 一、RBAC模型 二、实战应用 1. 建立用户、角色、资源实体类 2. 数据层查询角色资源 3. 业务层实现&#xff0c;调用数据层查询接口 4. SystemController控制器菜单获取方法 5. menu.jsp菜单页面实现 前言 本篇文章接SSM项目集成Spring Security 4.X版本&…

解决TortoiseGit软件Git Show log时显示Too many files to display的问题

1 问题描述 有时代码提交修改的文件比较多&#xff0c;当查看log时无法显示出来修改的文件列表&#xff0c;如下所示&#xff1a; 2 解决方法 将LogTooManyItemsThreshold尽可能配置得大一些。 三 参考资料 https://gitlab.com/tortoisegit/tortoisegit/-/issues/3878

常用通信总线学习——RS232与RS485

RS232概述 RS-232标准接口&#xff08;又称EIA RS-232&#xff09;是常用的串行通信接口标准之一&#xff0c;它是由美国电子工业协会(Electronic Industry Association&#xff0c;EIA)联合贝尔系统公司、调制解调器厂家及计算机终端生产厂家于1970年共同制定&#xff0c;其全…

C++核心编程:C++ 中的引用 笔记

2.引用 2.1 引用的基本使用 - 作用&#xff1a;给变量起别名 - 语法&#xff1a;数据类型 &别名 原名 #include<iostream> using namespace std; int main() {// 引用基本语法// 数据类型 &别名 原名int a 10;// 创建引用int &ref_a a;cout<<&qu…

快速入门Playwright框架:从零到自动化测试的第一步

Playwright框架&#xff1a; 背景介绍&#xff1a; ​ Playwright 是微软开发的 Web应用 的 自动化测试框架 。selenium相对于Playwright慢很多&#xff0c;因为Playwright是异步实现的&#xff0c;但是selenium是同步的&#xff0c;就是后一个操作必须等待前一个操作。 sel…

代码随想录 Leetcode226.翻转二叉树

题目&#xff1a; 代码(首刷看解析 2024年1月25日&#xff09;&#xff1a; class Solution { public:TreeNode* invertTree(TreeNode* root) {if(root nullptr) return root;swap(root->left,root->right);invertTree(root->left);invertTree(root->right);retu…

【ARMv8M Cortex-M33 系列 7 -- RA4M2 移植 RT-Thread 问题总结】

请阅读【嵌入式开发学习必备专栏 】 文章目录 问题小结栈未对齐 经过几天的调试&#xff0c;成功将rt-thead 移植到 RA4M2&#xff08;Cortex-M33 核&#xff09;上&#xff0c;thread 和 shell 命令已经都成功支持。 问题小结 在完成 rt-thread 代码 Makefile 编译系统搭建…

基于LSTM的负荷预测,基于BILSTM的负荷预测,基于GRU的负荷预测,基于BIGRU的负荷预测,基于BP神经网络的负荷预测

目录 背影 摘要 代码和数据下载&#xff1a;基于LSTM的负荷预测&#xff0c;基于BILSTM的负荷预测&#xff0c;基于GRU的负荷预测&#xff0c;基于BIGRU的负荷预测&#xff0c;基于BP神经网络的负荷预测资源-CSDN文库 https://download.csdn.net/download/abc991835105/8876806…

leetcode 第三弹

链表声明&#xff1a; * Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(n…

操作系统-进程通信(共享存储 消息传递 管道通信 读写管道的条件)

文章目录 什么是进程通信为什么进程通信需要操作系统支持共享存储消息传递直接通信方式间接通信方式 管道通信小结注意 什么是进程通信 分享吃瓜文涉及到了进程通信 进程通信需要操作系统支持 为什么进程通信需要操作系统支持 进程不能访问非本进程的空间 当进程P和Q需要…

【学网攻】 第(5)节 -- Cisco VTP的使用

文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口【学网攻】 第(4)节 -- 交换机划分Vlan 前言 网络已经成为了我们生活中不可或缺的一部分&#xff0c;它连接了世界各地的人们&#xff0c;让信息和资…

InitVerse:为云计算服务带来更高的透明度和可验证性

InitVerse&#xff1a;为云计算服务带来更高的透明度和可验证性 在云计算服务领域&#xff0c;透明度和可验证性是构建信任的关键要素。传统的云计算市场往往缺乏透明度&#xff0c;用户难以了解其数据和计算资源的实际使用情况。然而&#xff0c;通过利用区块链技术&#xff0…

简单快速取消AlertDialog的白色背景框,AlertDialog设置圆角背景

问题描述&#xff1a; 产品需求弹出的提示框是圆角&#xff0c;使用shape 设置圆角背景后&#xff0c;弹出的AlertDialog提示框四个角有白色的背景&#xff0c;据分析这个背景是 AlertDialog 父组件的背景色。 解决方法&#xff1a; 将Dialog的背景设置为透明色&#xff0c;代…

基于 Hologres+Flink 的曹操出行实时数仓建设

云布道师 曹操出行创立于 2015 年 5 月 21 日&#xff0c;是吉利控股集团布局“新能源汽车共享生态”的战略性投资业务&#xff0c;以“科技重塑绿色共享出行”为使命&#xff0c;将全球领先的互联网、车联网、自动驾驶技术以及新能源科技&#xff0c;创新应用于共享出行领域&…

【K8S 云原生】K8S的安全机制

目录 一、K8S安全机制概述 1、概念 2、请求apiserver资源的三个步骤&#xff1a; 一、认证&#xff1a;Anthentcation 1、认证的方式&#xff1a; 1、HTTP TOKEN&#xff1a; 2、http base&#xff1a; 3、http证书&#xff1a; 2、认证的访问类型&#xff1a; 3、签发…

Fluent Bit配置与使用——基于版本V2.2.2

Fluent Bit日志采集终端 文档适用版本&#xff1a;V2.2 1、日志文件处理流程 数据源是一个普通文件&#xff0c;其中包含 JSON 内容&#xff0c;使用tail插件记录日志&#xff0c;通过parsers进行格式化匹配&#xff08;图里没写&#xff09;&#xff0c;通过两个筛选器&…