【摘要】对于mysql主备实例,seconds_behind_master是衡量master与slave之间延时的一个重要参数。通过在slave上执行"show slave status;"可以获取seconds_behind_master的值。

Seconds_Behind_Master

对于mysql主备实例,seconds_behind_master是衡量master与slave之间延时的一个重要参数。通过在slave上执行"show slave status;"可以获取seconds_behind_master的值。

原始实现

Definition:The number of seconds that the slave SQL thread is behind processing the master binary log.

Type:time_t(long)

计算方式如下:

rpl_slave.cc::show_slave_status_send_data()
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() - mi->rli->last_master_timestamp) -
mi->clock_diff_with_master);
protocol->store(
(longlong)(mi->rli->last_master_timestamp ? max(0L, time_diff) : ));
}

主要分为以下两种情况:

• SQL线程等待IO线程获取主机binlog,此时seconds_behind_master为0,表示备机与主机之间无延时;

• SQL线程处理relay log,此时seconds_behind_master通过(long)(time(0) – mi->rli->last_master_timestamp) – mi->clock_diff_with_master计算得到;

last_master_timestamp

定义:

• 主库binlog中事件的时间。

• type: time_t (long)

计算方式:

last_master_timestamp根据备机是否并行复制有不同的计算方式。

非并行复制:

rpl_slave.cc:exec_relay_log_event()
if ((!rli->is_parallel_exec() || rli->last_master_timestamp == ) &&
!(ev->is_artificial_event() || ev->is_relay_log_event() ||
(ev->common_header->when.tv_sec == ) ||
ev->get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT ||
ev->server_id == ))
{
rli->last_master_timestamp= ev->common_header->when.tv_sec +
(time_t) ev->exec_time;
DBUG_ASSERT(rli->last_master_timestamp >= );
}

在该模式下,last_master_timestamp表示为每一个event的结束时间,其中when.tv_sec表示event的开始时间,exec_time表示事务的执行时间。该值的计算在apply_event之前,所以event还未执行时,last_master_timestamp已经被更新。由于exec_time仅在Query_log_event中存在,所以last_master_timestamp在应用一个事务的不同event阶段变化。以一个包含两条insert语句的事务为例,在该代码段的调用时,打印出event的类型、时间戳和执行时间

create table t1(a int PRIMARY KEY AUTO_INCREMENT ,b longblob) engine=innodb;
begin;
insert into t1(b) select repeat('a',);
insert into t1(b) select repeat('a',);
commit;
10T06::.628554Z  [Note] [MY-] [Repl] event_type:  GTID_LOG_EVENT
--10T06::.628601Z [Note] [MY-] [Repl] event_time:
--10T06::.628614Z [Note] [MY-] [Repl] event_exec_time:
--10T06::.628692Z [Note] [MY-] [Repl] event_type: QUERY_EVENT
--10T06::.628704Z [Note] [MY-] [Repl] event_time:
--10T06::.628713Z [Note] [MY-] [Repl] event_exec_time:
--10T06::.629037Z [Note] [MY-] [Repl] event_type: TABLE_MAP_EVENT
--10T06::.629057Z [Note] [MY-] [Repl] event_time:
--10T06::.629063Z [Note] [MY-] [Repl] event_exec_time:
--10T06::.644111Z [Note] [MY-] [Repl] event_type: WRITE_ROWS_EVENT
--10T06::.644149Z [Note] [MY-] [Repl] event_time:
--10T06::.644156Z [Note] [MY-] [Repl] event_exec_time:
--10T06::.520272Z [Note] [MY-] [InnoDB] Page cleaner took 9185ms to flush and evict pages
--10T06::.982458Z [Note] [MY-] [Repl] event_type: TABLE_MAP_EVENT
--10T06::.982488Z [Note] [MY-] [Repl] event_time:
--10T06::.982495Z [Note] [MY-] [Repl] event_exec_time:
--10T06::.569345Z [Note] [MY-] [Repl] event_type: WRITE_ROWS_EVENT
--10T06::.569376Z [Note] [MY-] [Repl] event_time:
--10T06::.569384Z [Note] [MY-] [Repl] event_exec_time:
--10T06::.506176Z [Note] [MY-] [InnoDB] Page cleaner took 9352ms to flush and evict pages
--10T06::.202507Z [Note] [MY-] [Repl] event_type: XID_EVENT
--10T06::.202539Z [Note] [MY-] [Repl] event_time:
--10T06::.202546Z [Note] [MY-] [Repl] event_exec_time:

并行复制:

rpl_slave.cc   mts_checkpoint_routine
ts = rli->gaq->empty()
?
: reinterpret_cast<Slave_job_group *>(rli->gaq->head_queue())->ts;
rli->reset_notified_checkpoint(cnt, ts, true);
/* end-of "Coordinator::"commit_positions" */

在该模式下备机上存在一个分发队列gaq,如果gaq为空,则设置last_commit_timestamp为0;如果gaq不为空,则此时维护一个checkpoint点lwm,lwm之前的事务全部在备机上执行完成,此时last_commit_timestamp被更新为lwm所在事务执行完成后的时间。该时间类型为time_t类型。

ptr_group->ts = common_header->when.tv_sec +
(time_t)exec_time; // Seconds_behind_master related
rli->rli_checkpoint_seqno++;
if (update_timestamp) {
mysql_mutex_lock(&data_lock);
last_master_timestamp = new_ts;
mysql_mutex_unlock(&data_lock);
}

在并行复制下,event执行完成之后才会更新last_master_timestamp,所以非并行复制和并行复制下的seconds_behind_master会存在差异。

clock_diff_with_master

定义:

• The difference in seconds between the clock of the master and the clock of the 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 the I/O thread does a SELECT UNIX_TIMESTAMP() on the master.

• type: long

rpl_slave.cc::get_master_version_and_clock()
if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&
(master_res= mysql_store_result(mysql)) &&
(master_row= mysql_fetch_row(master_res)))
{
mysql_mutex_lock(&mi->data_lock);
mi->clock_diff_with_master=
(long) (time((time_t*) ) - strtoul(master_row[], , ));
DBUG_EXECUTE_IF("dbug.mts.force_clock_diff_eq_0",
mi->clock_diff_with_master= ;);
mysql_mutex_unlock(&mi->data_lock);
}

该差值仅被计算一次,在master与slave建立联系时处理。

其他

exec_time

定义:

• the difference from the statement’s original start timestamp and the time at which it completed executing.

• type: unsigned long

struct timeval end_time;
ulonglong micro_end_time = my_micro_time();
my_micro_time_to_timeval(micro_end_time, &end_time);
exec_time = end_time.tv_sec - thd_arg->query_start_in_secs();

时间函数

(1)time_t time(time_t timer) time_t为long类型,返回的数值仅精确到秒;

(2)int gettimeofday (struct timeval *tv, struct timezone *tz) 可以获得微秒级的当前时间;

(3)timeval结构

#include <time.h>
stuct timeval {
time_t tv_sec; /*seconds*/
suseconds_t tv_usec; /*microseconds*/
}

总结

使用seconds_behind_master衡量主备延时只能精确到秒级别,且在某些场景下,seconds_behind_master并不能准确反映主备之间的延时。主备异常时,可以结合seconds_behind_master源码进行具体分析。

点击关注,第一时间了解华为云新鲜技术~

【华为云技术分享】数据库开发:MySQL Seconds_Behind_Master简要分析的更多相关文章

  1. 【华为云实战开发】10.经典的C++项目怎么在云端开发?【华为云技术分享】

    1 概述 1.1 文章目的 本文主要想为研发C++项目的企业或个人提供上云指导,通过本文中的示例项目 “音频解析器”,为开发者提供包括项目管理,代码托管,代码检查,编译构建,测试管理的操作指导,覆盖软 ...

  2. MySQL数据库开发的36条原则【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...

  3. 【华为云实战开发】9.如何进行PHP项目的快速搭建并实现CICD?【华为云技术分享】

    1 概述 1.1 文章目的 本文主要想为研发PHP项目的企业或个人提供上云指导,通过本文中的示例项目 “workerman-todpole”,为开发者提供包括项目管理,代码托管,代码检查,编译构建,测 ...

  4. MySQL 8.0新增特性详解【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...

  5. Python开发GUI工具介绍,实战:将图片转化为素描画!【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...

  6. 性能达到原生 MySQL 七倍,华为云 Taurus 技术解读【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...

  7. 【华为云实战开发】8.如何快速搭建C#网站并实现持续集成?【华为云技术分享】

    1 概述 1.1 文章目的 本文通过一个实例介绍如何使用软件开发服务DevCloud完成一个C#Web项目的开发. 1.2 项目详情 1. 项目名称:超级冷笑话网站 2. 项目简介:一个Web网站,包 ...

  8. 补习系列(17)-springboot mongodb 内嵌数据库【华为云技术分享】

    目录 简介 一.使用 flapdoodle.embed.mongo A. 引入依赖 B. 准备测试类 C. 完善配置 D. 启动测试 细节 二.使用Fongo A. 引入框架 B. 准备测试类 C.业 ...

  9. 华为云实战开发】5.如何快速创建免费Git代码仓库【华为云技术分享】

    1 文章目的 本文主要帮助已经掌握或者想要掌握Git的开发者,如何更好的应用Git,以及更好的将Git与DevCloud结合应用. 2 概述 2.1 版本控制系统介绍 从狭义上来说,版本控制系统是软件 ...

随机推荐

  1. 常用的code snipper

    Xcode 10.2.1 版本,自动代码提示功能延迟很大,很多情况下代码提示甚至会无效,但是code snippet 唤起的响应很快,从提高效率的情况考虑,即使系统提供的代码提示制作成code sni ...

  2. 17-4 delete-truncate语句-练习

    --删除数据语句: --delete from 表名 where ... --delete语句如果不加where条件,表示将表中所有的数据都删除,加where条件后,会按照where条件进行删除. - ...

  3. [推荐]大量 Blazor 学习资源(一)

    前言 / Introduction Blazor 是什么? Blazor 允许您使用 C# 而不是 JavaScript 构建交互式 Web UI. Blazor 应用由使用 C#.HTML 和 CS ...

  4. Cube-UI组件中create-api 模块的基本使用

    1.这个模块的功能是什么? 官方文档是这样解释的: 该模块默认暴露出一个 createAPI 函数,可以实现以 API 的形式调用自定义组件.并且既可以在 Vue 实例上下文中调用,也可以在普通 js ...

  5. Java——反射三种方式的效率对比

    转载自:https://blog.csdn.net/aitcax/article/details/52694423 1 使用field(效率最高)             long start = S ...

  6. mvc的视图渲染方式

    ModelAndView ModelAndView vm = new ModelAndView(); //封装要显示在试图上的数据 vm.addObject("msg"," ...

  7. 阿里短信回持.net sdk的bug导致生产服务cpu 100%排查

    一:背景 1. 讲故事 去年阿里聚石塔上的所有isv短信通道全部对接阿里通信,我们就做了对接改造,使用阿里提供的.net sdk. 网址:https://help.aliyun.com/documen ...

  8. 项目readme文件目录生成工具 treer

    生成目录的工具呢有tree和treer,但是tree不知道怎么忽略node_modules文件夹, 而treer就简单了,下面就是基本的命令了 其中-i是指忽略xxx, -e是指导出 安装 npm i ...

  9. Docker 入门:Dockerfile

    主要内容: 什么是 Dockerfile 查看 DockerHub 中镜像的 Dockerfile Dockerfile 编写 Dockerfile 常用命令 什么是 Dockerfile 使用 Do ...

  10. 用tarjan求LCA板子(比倍增快)

    懒!!直接转载!!!! https://solstice23.top/archives/62