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

    文章

    762

    浏览量

    44117
  • MySQL
    +关注

    关注

    1

    文章

    804

    浏览量

    26544

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

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

收藏 人收藏

    评论

    相关推荐

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

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

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

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

    时间的简介与实现

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

    mysql数据库同步原理

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

    腾讯云打造MySQL 8.0全新引擎,进一步加速客户产业升级

    据介绍,腾讯云数据库 MySQL 8.0的内核可以百分百完全兼容主流MySQL分支。相比官方版本,无论是单机模式、异步模式还是同步模式下, MySQL
    的头像 发表于 07-09 14:54 2354次阅读

    MySQL 5.7与MySQL 8.0 性能对比

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

    UNIX时间和北京时间的相互转换

    )开始所经过的秒数,不考虑闰秒。一个小时表示为UNIX时间格式为:3600秒;一天表示为UNIX时间为86400秒,闰秒不计算。在很多的数据
    发表于 11-21 19:06 11次下载
    UNIX<b class='flag-5'>时间</b><b class='flag-5'>戳</b>和北京<b class='flag-5'>时间</b>的相互转换

    uCOS-III(2) 时间

    时间时间简介时间的实现时间
    发表于 01-14 16:04 4次下载
    uCOS-III(2) <b class='flag-5'>时间</b><b class='flag-5'>戳</b>

    Java时间的使用

    ());System.out.println(nowTime); 输出: 2022-06-08 11:15:51.014 Long型时间 Long timeLong
    的头像 发表于 01-13 15:30 759次阅读

    Java时间的使用

    Java时间的使用
    的头像 发表于 11-06 16:04 190次阅读
    Java<b class='flag-5'>中</b><b class='flag-5'>时间</b><b class='flag-5'>戳</b>的使用

    请问mysql8.0不能在grant时创建用户是什么原因?

    用习惯了MySQL5.7,当在MySQL8.0里创建用户时,习惯性直接敲GRANT指令,结果报错了
    的头像 发表于 08-11 10:16 2210次阅读

    mysql主从复制的原理

    其重放在自己的数据库binlog(Binary Log): 是MySQL中用于记录主数据库上的所有数据变更的二进制文件。
    的头像 发表于 11-16 14:18 486次阅读

    mysql8.0默认字符集是什么

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

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

    mysql数据库数据恢复环境: 本地服务器,windows server操作系统 ,部署有mysql单实例,数据库引擎类型为innodb,独立表空间,无数据库备份,未开启binlog
    的头像 发表于 12-08 14:18 1132次阅读
    数据库数据恢复—未开启<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 511次阅读
    GitHub底层数据库无缝升级到<b class='flag-5'>MySQL</b> <b class='flag-5'>8.0</b>的经验