多种方式告诉你如何计算DM同步数据到TiDB的延时时间
背景
用户在做技术选型的过程中,总是会对一些数据指标比较关心,特别是在和竞品相比较的时候,更加需要一些有说服力的数据。基于MySQL开发的项目在迁移到TiDB的时候,使用DM同步数据是必不可少的一个环节,我在最近的一次POC中就碰到了这样一个需求,需要评估一个具体的延时时间参考值,因为用户在迁移前期的过渡阶段是把TiDB作为MySQL的从库,有些场景对这个延时很敏感,如果延时太大会直接影响业务。
由于DM并不能直接看到整个链路的延时时间,所以我们必须另辟蹊径找一些办法来实现,以下是我实践过的几种办法,也希望能抛砖引玉,带出其他大佬给社区带来更好的方案。
我的思路比较简单,就是分别根据上下游事务的某个时间点来计算时间差,这个时间差应该要精确到毫秒级,可以从三个方向入手:
Binlog Position
TiDB General log
SQL自动记录时间
接下来就分别看一下如何实现。
基于Binlog Position
DM增量同步是基于订阅MySQL Binlog来实现的,所以首先考虑的办法就是通过Binlog Position来定位某一个事务,只要分别找到同一个Position在Binlog和DM-Worker Log中记录的时间,就可以大致计算出这个时间差。
我使用如下一张测试表来演示这个过程:
CREATE TABLE `table1` (
`id` int(11) NOT NULL,
`mysql_created` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
在DM Task完全启动成功之后,我们往MySQL里的table1插入一条数据:
insert into table1 values(1,null);
插入成功后我们找到这个事务第一个events的position,这个示例中是1422:
接下来去binlog文件中解析出这段范围内的事务内容,里面有我们需要的时间:
注意看里面的TIMESTAMP内容,意思是事务开始时的时间是21:45:38:572
,原始内容精确到了微秒级别,我们这里只取毫秒来计算。
然后拿事务开始的position去dm-worker的日志中搜索相应的内容,当binlog被处理完成后会输出flushed checkpoint
字样的内容,我们根据关键字去日志文件中搜索:
从这里可以得到1422被写入完成的时间是21:45:38.603
,前后相减一下大概时间差是31ms。
要注意的是,我理解整个链路的过程应该是:mysql(事务开始)->binlog->dm-worker->tidb->dm-worker,相当于TiDB写完后多了一个通知dm-worker的过程。
基于TiDB General log
第二种与前一种类似,我希望能定位到事务实际被TiDB执行完成的时间,这时候可以借助TiDB的GENERAL_LOG
功能,用事务号(TSO)去定位。
我们首先打开TiDB实例的General Log开关:
mysql> set tidb_general_log=1;
Query OK, 0 rows affected (0.08 sec)
前半部分和之前一样,还是去binlog文件中找到MySQL事务开始时间戳,这里是22:08:55:419
:
然后打开TiBD的Dashboard页面,用如下关键字搜索TiDB节点的日志:
虽然这个页面能看到日志的记录时间,但是存在两个问题,一个是不能精确到毫秒,第二个这并不是事务的提交时间,我们需要进一步根据事务号(TSO)去原始文件中搜索准确时间。
这里的commit时间是22:08:55.434
,前后相减的时间差大概15ms。
这里也可以一步到位直接去原始log文件去搜,省去Dashboard查询TSO的过程。
这个链路过程是:mysql(事务开始)->binlog->dm-worker->tidb(事务提交)。
基于SQL自动记录时间
前面两种方法都要各种搜索日志稍微有点麻烦,本着将偷懒进行到底的精神,能不能直观地看出上下游各自的时间?最理想的情况是:一句SQL就能查出来。
从前面的测试中可以发现,时间字段设置当前时间为默认值只对上游生效,同步到TiDB的时候是把实际值传过去了,并不是根据字段定义生成新值。因此,我希望数据到TiBD的时候也能生成当前时间写入某个字段,但是这个字段不能在MySQL中存在,也就是说上下游数据结构不一样。
那DM可以支持这种同步吗?必然是可以的。
关于上下游异构同步官网文档有详细介绍,大家可以参考文档:https://docs.pingcap.com/zh/tidb-data-migration/stable/manage-schema。
我们要使用的带默认值异构同步其实更简单,DM不用做任何操作就能支持。
我们在前面的DM Task完全不动的情况下,只给下游TiDB的table1增加一个字段:
alter table table1 add COLUMN tidb_created timestamp(3) NOT NULL DEFAULT current_timestamp(3);
然后往上游插入一条测试数据:
insert into table1 values(3,null);
插入成功后去TiDB中查询这个表,两个创建时间都能看到了:
是不是非常简单。
这个链路的过程是:mysql(事务开始)->binlog->dm-worker->tidb(事务开始)。
总结
以上3种方式从不同维度计算了一次数据同步的延时情况,这个数据具有一定的参考性。但是使用的过程中要注意每一种的区别,选择你最适合最关心的指标来作为参考。
本文如有不正确的地方欢迎指出,当然了,也欢迎大家推荐更好的方案,一起交流~
多种方式告诉你如何计算DM同步数据到TiDB的延时时间的更多相关文章
- MYSQL5.7实时同步数据到TiDB
操作系统:CentOS7 mysql版本:5.7 TiDB版本:2.0.0 同步方法:使用TiDB提供的工具集进行同步 说明: 单机mysql同步时,可以直接使用binlog同步, 但mysql集群进 ...
- C# 中web如何定时同步数据
之前做定时器同步方法试过很多方法, 不过都有些问题 1)quartz + IIS 方式(web项目发布到IIS上,出现IIS应用池回收问题) 2)用线程Timer方式 (出现多个线程同步同个任务问题) ...
- Sql2008 r2 使用ftp 公布和订阅方式同步数据
Sql2008 r2使用公布和订阅方式同步数据 因为非常多图片 本篇没有图片 详情能够进入下载页 http://download.csdn.net/download/yefighter/760374 ...
- 云小课 | 搬迁本地数据至OBS,多种方式任你选
摘要:搬迁本地数据至OBS,包括OBS工具方式.CDM方式.DES磁盘方式.DES Teleport方式和云专线方式,每种方式特点不同,本节课我们就一起看看有什么区别. 已有的业务数据可能保存在本地的 ...
- Spring学习总结(一)——Spring实现IoC的多种方式
控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法.没有IoC的程序中我们使用面向对象编程对象的创 ...
- sql语句分页多种方式ROW_NUMBER()OVER
sql语句分页多种方式ROW_NUMBER()OVER 摘自: http://www.cnblogs.com/CodingArt/articles/1692468.html 方式一 select to ...
- Windows 之间用rsync同步数据(cwRsyncServer配置)
rsync是一款优秀的数据同步软件,在跨服务器,跨机房,跨国备份服务器的首选工具,下面就来介绍下如何配置安装cwRsyncServer很大多数软件一样是B/C架构,cwRsyncServer是rsyn ...
- Spring实现Ioc的多种方式--控制反转、依赖注入、xml配置的方式实现IoC、对象作用域
Spring实现Ioc的多种方式 一.IoC基础 1.1.概念: 1.IoC 控制反转(Inversion of Control) IoC是一种设计思想. 2.DI 依赖注入 依赖注入是实现IoC的一 ...
- Elasticsearch-2.4.3的3节点安装(多种方式图文详解)(含 head、kopf、marvel、shield和watcher插件安装和使用)
前提: Elasticsearch-2.4.3的下载(图文详解) Elasticsearch-2.4.3的单节点安装(多种方式图文详解) 我这里,以192.168.80.10(HadoopMaster ...
随机推荐
- 第三十一个知识点:Game Hopping证明
第三十一个知识点:Game Hopping证明 关于安全证明, 目前主流的方法有安全归约证明 (由 single game 实现) 和 Game Hopping (由 game sequence 实现 ...
- 解决opencv:AttributeError: 'NoneType' object has no attribute 'copy'
情况一: 路径中有中文,更改即可 情况二:可以运行代码,在运行结束时显示 AttributeError: 'NoneType' object has no attribute 'copy' 因为如果是 ...
- CapstoneCS5212替代IT6516方案|DP转VGA芯片|替代兼容IT6516
台湾联阳IT6516是一种高性能的DP显示端口到VGA转换器方案芯片.IT6516结合DisplayPort接收器和三重DAC,通过转换功能支持DisplayPort输入和VGA输出.内置Displa ...
- Spring企业级程序设计 • 【第6章 深入Spring MVC开发】
全部章节 >>>> 本章目录 6.1 模型数据解析及控制器返回值 6.1.1 ModelAndView多种用法 6.1.2 Map添加模型数据和返回String类型值 6 ...
- 使用 JavaScript 根据消费金额和消费者是否为会员确定折扣,最终核算实际应该支付的金额
查看本章节 查看作业目录 需求说明: 根据消费金额和消费者是否为会员确定折扣,最终核算实际应该支付的金额 消费金额在 200 元以上的会员折扣是 7.5 折,消费金额没有达到 200 元的会员折扣是 ...
- 编写Java程序,在子类老虎中重写父类动物的吃食方法
返回本章节 返回作业目录 需求说明: 在子类老虎中重写父类动物的吃食方法 实现思路: 在子类老虎中重写父类动物的吃食方法的实现思路如下: 创建各种动物的父类Animal类,在该类中定义eat()方法. ...
- Docker | dockerfile 文件编写
dockerfile 的作用 dockerfile 作用就是制作镜像,保持开发,测试,生产环境的一致性. 直接将容器制作为镜像 制作新的镜像 # 把容器按照自己的需求个性完之后,就可以创建自己的镜像的 ...
- 记一次log4j2引发的渗透测试
前言 记一次log4j2打入内网并用CVE-2021-42287.CVE-2021-42278获取到DC权限的靶场渗透. 外网打点 首先对web进行端口扫描,发现38080端口和22端口 访问一下38 ...
- golang 开源代理
export GOPROXY=https://goproxy.io 设置好之后就可以用go get 下载被墙的包了 项目地址:https://github.com/goproxyio/goproxy
- 手写RPC-简陋版
前言 最近不小心被隔离,放假思考一番,决定开始在手写序列.这个序列在之前看Nacous和网关源码的时候就有想法,只是一直没落实下来,趁着隔离行动起来. 必备知识介绍 序列化与反序列化 序列化是把对象的 ...