0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

谈谈MySQL 8.0 binlog中精准的时间戳

OSC开源社区 来源:爱可生开源社区 2023-12-28 09:37 次阅读

1、相关解释

immediate_commit_timestamp:代表是当前数据库提交的时间,从库/主库都分别代表其提交的时间。

original_commit_timestamp:代表主库提交的时间,不管有多少级联的从库这个时间永远是主库提交事务时候的时间。当然在主库上其就等于 immediate_commit_timestamp 的时间。

它们的生成时间都是在从 binlog cache 写入到 binlog 文件的时候,生成 GTID event 的时候,也就是 commit 的 flush 阶段,我们简称这个为 提交时间

但是需要注意的是 MGR 中主库的 original_commit_timestamp 和 immediate_commit_timestamp 生成稍有提前(group_replication_trans_before_commit),并不是这里说的提交时间。

2、生成流程

2.1 关于 thd->variables.original_commit_timestamp

因为 original_commit_timestamp 来自这个值,一般情况下其值都是 UNDEFINED_COMMIT_TIMESTAMP,但是从库上这个值会在应用 GTID event 的时候更改为主库带过来的 original_commit_timestamp,因为主库 original_commit_timestamp 就是提交时间,因此从库的 thd->variables.original_commit_timestamp 也就设置为了主库的提交时间。

但是有一个例外,就是 5.7 向 8.0 同步的时候,因为没有这个值因此会被设置为 0。如下:

# original_commit_timestamp=0 (1970-01-01 0800.000000 CST)
# immediate_commit_timestamp=1703237689977004 (2023-12-22 1749.977004 CST)

2.2 生成方式

这个其实比较简单,就是在函数 MYSQL_BIN_LOG::write_transaction 中生成的,大概为:

immediate_commit_timestamp = 获取的当前时间
original_commit_timestamp = thd->variables.original_commit_timestamp
(前面描述了thd->variables.original_commit_timestamp主库不会设置为特定的值,其为 UNDEFINED_COMMIT_TIMESTAMP)

如果 original_commit_timestamp 等于 UNDEFINED_COMMIT_TIMESTAMP,那么它就是主库,应该将设置
original_commit_timestamp = immediate_commit_timestamp,这样主库的 original_commit_timestamp 
和 immediate_commit_timestamp 就相同了

否则 original_commit_timestamp 有特定的值,那么就是从库,因为这个值来自 
thd->variables.original_commit_timestamp,前面说了他是应用 GTID event 的值。

2.3 相关警告

当发现从库的提交时间还比主库的提交时间更慢的时候,显然这是不合适的,就会出现这个警告如下:

if(original_commit_timestamp>immediate_commit_timestamp&&
!thd->rli_slave->get_c_rli()->gtid_timestamps_warning_logged){//如果原始时间还在于了当前服务器的提交时间,这是常见的警告
LogErr(WARNING_LEVEL,ER_INVALID_REPLICATION_TIMESTAMPS);//则报警

这就是大家经常遇到的警告。

Invalidreplicationtimestamps:originalcommittimestampismorerecentthanthe
immediatecommittimestamp.Thismaybeanissueifdelayedreplicationisactive.
Makesurethatservershavetheirclockssettothecorrecttime.Nofurther
messagewillbeemitteduntilaftertimestampsbecomevalidagain."

3、其运维中的意义

3.1 在延时从库中的应用

如果配置了延迟从库,则使用的是 immediate_commit_timestamp 作为延迟从库应用 event 的计算标准,因为这里 event 来自 relay log,因此 immediate_commit_timestamp 是 IO 线程连接库(A->B->C,C 为延迟从库,则这里为B库提交事务的时间)的事务提交时间,在函数 sql_delay_event 中有如下计算方式:

sql_delay_end=ceil((static_cast(ev)
->immediate_commit_timestamp)/
1000000.00)+
sql_delay;

而对于不支持的延时从库则计算为:

sql_delay_end=ev->common_header->when.tv_sec+
rli->mi->clock_diff_with_master+sql_delay;

对于 immediate_commit_timestamp 和 ev->common_header->when.tv_sec 是有很大区别的,后者为 binlog header 中 timestamp 的时间,其在整个复制链路中并不会改变,其几乎为命令发起的时间,而不是事务提交的时间。我们以 A->B->C 为列,其中 C 为一个延迟从库。

支持 immediate_commit_timestamp 的情况:C 的延迟计算是以B库提交时刻的时间为计算标准的。也就是其延迟是 B 库提交后多久 C 库应用。

不支持 immediate_commit_timestamp 的情况:C 的延迟计算是以 A 库命令发起的时间为计算标准的。也就是其延迟是 A 库命令发起后多久 C 库应用。

很显然前者的计算方式更为靠谱。在延迟从库在等待的时候其线程的状态为:

WaitinguntilMASTER_DELAYsecondsaftermasterexecutedevent

3.2 主库判定事务的提交时刻和语句发起时间

某些时候我们可能需要知道语句什么时候发起执行的,什么时候提交完成的,这个时候我们考虑使用 immediate_commit_timestamp 和 event header 的 timestamp 进行对比。

对于自动提交的 DML 语句,则 GTID event header 的 timestamp 为语句发起的时间,而 GTID event 的 immediate_commit_timestamp 为事务提交的时间,如果差值太大,可能是遇到了锁(MDL LOCK 或 row lock)之类的问题。如下图:

1ad9362e-a4a9-11ee-8b88-92fbcf53809c.jpg 1adfae50-a4a9-11ee-8b88-92fbcf53809c.jpg

对于非自动提交的事务,则 GTID event 的 immediate_commit_timestamp 为事务提交的时间,但是语句开始执行的时间需要查看具体语句的 event 才可以,不能查看 GTID event header 的 timestamp,这是 commit 命令发起的时间,如下图:

1aebfc5a-a4a9-11ee-8b88-92fbcf53809c.jpg 1af1ade4-a4a9-11ee-8b88-92fbcf53809c.jpg

当然类似,还可以获取从库的 binlog 信息来比对主库是什么时候发起语句的,什么时候提交事务的,从库又是什么时候提交事务的。类似如下图,这是我的一个从库,我这里是一个自动提交的 DML 语句

1af5f7be-a4a9-11ee-8b88-92fbcf53809c.jpg

很明显,主库发起语句时间和主库提交时间以及从库提交时间都有一定的差值。

主库发起语句时间:1209

主库提交事务时间:1213

从库提交事务时间:1259

3.3 更加精确的延迟

这部分你在官方文档有说明,其中主要包含 3 个视图:

ps.replication_applier_status_by_worker: SQL 线程或者 WORKER 执行相关

ps.replication_connection_status: IO 线程相关

ps.replication_applier_status_by_coordinator: 协调线程相关

其中大部分和 timestamp 相关的字段的都是自解释的,而在 ps.replication_applier_status_by_coordinator 和 ps.replication_applier_status_by_worker 中有两类字段类似 XXX_BUFFER_TIMESTAMP,XXX_APPLY_TIMESTAMP 比如:

LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP: 表示协调线程将事务分发给 WORKER 线程的时间

LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP: 表示应用完事务的时间

具体代码中可以断点在:

Relay_log_info::finished_processing

Relay_log_info::started_processing

上进行观察,实际上是 Relay_log_info 中多了如下信息:

  /**
    Stores information on the last processed transaction or the transaction
    that is currently being processed.

    STS:
    - timestamps of the currently applying/last applied transaction

    MTS:
    - coordinator thread: timestamps of the currently scheduling/last scheduled
      transaction in a worker's queue
    - worker thread: timestamps of the currently applying/last applied
      transaction
  */
  Gtid_monitoring_info *gtid_monitoring_info;

每个 WORKER 和协调线程都包含了这样一个事务的监控信息,因此可以在视图中打印出来。

显然我们就可以通过各种从库中执行的 timestamp 的时间和主库提交时间也就是 ORIGINAL_COMMIT_TIMESTAMP 计算出来精确的延迟。







审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • SQL
    SQL
    +关注

    关注

    1

    文章

    738

    浏览量

    43462
  • MySQL
    +关注

    关注

    1

    文章

    775

    浏览量

    26005

原文标题:再谈MySQL 8这两个精准的时间戳

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    时间同步获取时间

    新手一枚,对单片机原理还不是很清楚,求教:TinyOS时间同步首先要获取本地时间,getStartTime(),想知道它是怎么获取时间
    发表于 03-20 10:37

    如何查询时间

    /Tools/unixtime.aspx,可以看到如下截图: :红色方框的数字1455526433就是我们需要的时间
    发表于 02-15 16:54

    大数据监控binlog组件的maxwell组件

    大数据实时监控mysql数据库binlog(二)
    发表于 05-16 11:24

    binlog有什么意义/工作模式/优缺点

      Linux运维是现下较为火热的职业岗位之一。学习Linux技术的人越来越多。Linux运维学习过程binlog有什么意义?binlog有哪些工作模式?都有哪些优缺点?binlog
    发表于 01-29 17:24

    ERTC 时间的使用

    示例目的演示AT32F415以及AT32F421 ERTC时间的使用。支持型号:AT32F415xxAT32F421xx主要使用外设:ERTC1.快速使用方法1.1 硬件资源1
    发表于 08-18 19:55

    什么是Unix时间

    1.什么是Unix时间Unix时间是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。 [1]Unix时间
    发表于 01-12 08:30

    时间的简介与实现

    时间时间简介时间的实现时间
    发表于 02-28 06:23

    mysql数据库同步原理

    了数据库的访问压力,提升整个系统的性能和可用性,降低了大访问量引发数据库宕机的故障率。 binlog简介 MySQL主从同步是基于binlog文件主从复制实现,为了更好的理解主从同步过程,这里简单介绍一下
    发表于 09-28 11:49 0次下载
    <b class='flag-5'>mysql</b>数据库同步原理

    MySQL 5.7与MySQL 8.0 性能对比

    背景 测试mysql5.7和mysql8.0分别在读写,选定,只写模式下不同并发时的性能(tps,qps) 最早 测试使用版本为mysql5.7.22和mysql8.0.15 sysb
    的头像 发表于 11-03 09:26 1.4w次阅读
    <b class='flag-5'>MySQL</b> 5.7与<b class='flag-5'>MySQL</b> <b class='flag-5'>8.0</b> 性能对比

    关于MySQL8.0版本选型的小技巧

    MySQL 8.0 第一个GA(General Availability)版本(正式、可用于生产的版本)于2018/4/19发布至今已有3年。8.0是一个全新的版本,增加了数百项功能新特性,重构
    的头像 发表于 03-29 13:45 819次阅读
    关于<b class='flag-5'>MySQL8.0</b>版本选型的小技巧

    mysql主从复制的原理

    MySQL主从复制是一种数据库复制技术,它允许将一个MySQL数据库的更新操作自动复制到其他MySQL数据库上的过程。主要通过MySQLbinlo
    的头像 发表于 11-16 14:18 273次阅读

    mysql8.0默认字符集是什么

    MySQL 8.0 默认字符集是 utf8mb4。 MySQL 8.0 是当前最新的开源关系型数据库管理系统,由Oracle公司开发和维护。MySQ
    的头像 发表于 11-16 14:48 1107次阅读

    MySQL5.7数据导入8.0版本,这3款工具值得收藏!

    MySQL 5.7数据库迁移到MySQL 8.0可以使用NineData、MySQL Shell、Percona XtraBackup和Liquibase等工具。每个工具都有自己的优
    的头像 发表于 11-29 16:47 425次阅读
    <b class='flag-5'>MySQL</b>5.7数据导入<b class='flag-5'>8.0</b>版本,这3款工具值得收藏!

    数据库数据恢复—未开启binlogMysql数据库数据恢复案例

    mysql数据库数据恢复环境: 本地服务器,windows server操作系统 ,部署有mysql单实例,数据库引擎类型为innodb,独立表空间,无数据库备份,未开启binlog
    的头像 发表于 12-08 14:18 379次阅读
    数据库数据恢复—未开启<b class='flag-5'>binlog</b>的<b class='flag-5'>Mysql</b>数据库数据恢复案例

    GitHub底层数据库无缝升级到MySQL 8.0的经验

    目标 (SLO) 的情况下升级主机集群(1200 多台 MySQL 主机)绝非易事。其团队表示,为了升级到 MySQL 8.0,他们规划、测试和升级本身总共花费了一年多的时间,并且需要
    的头像 发表于 12-13 10:21 230次阅读
    GitHub底层数据库无缝升级到<b class='flag-5'>MySQL</b> <b class='flag-5'>8.0</b>的经验