服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Mysql - MySQL:级联从库延迟数据库的延迟计算问题

MySQL:级联从库延迟数据库的延迟计算问题

2023-12-29 01:00未知服务器之家 Mysql

本文主要讨论的还是5.7,8.0没有实际测试,这里简单记录。 一、问题说明 最近在处理一个主从问题的时候,发现一个比较奇怪的现象,这个主从是级联的也就是A-B-C库,B库问题处理后先启动了B库追数据,然后修复C库启动追延迟,

本文主要讨论的还是5.7,8.0没有实际测试,这里简单记录。

MySQL:级联从库延迟数据库的延迟计算问题

一、问题说明

最近在处理一个主从问题的时候,发现一个比较奇怪的现象,这个主从是级联的也就是A->B->C库,B库问题处理后先启动了B库追数据,然后修复C库启动追延迟,这个时候观察到的B库和C库的延迟分别为20000多秒和900多秒,显然这个差距是非常大的,而级联又是平时用得很多的一种方式。 这里实际上C库的延迟应该比B库更大,那么级联从库中C库的延迟计算到底是怎么样的呢?

这里我们简单探讨一下,未考虑清楚的地方还请见谅,下面我们也用A B C来代表主库、从库1、从库2。

二、延迟计算和级联从库C

一般来讲我们在讨论延迟的时候,延迟的计算公式大概如下,当然准确来说是单SQL线程(非MTS)下计算延迟的公式。

MySQL:级联从库延迟数据库的延迟计算问题

其中在主库row格式的binlog其query event中exec time的时间基本为0,因此B库在计算延迟的时候基本可以在公式中简化掉。

而在级联从库C中,其binlog来自B库,那么在B库中的binlog如何记录的就成了关键,那么其有2个关键就是:

(1) Event中header中timestamp的时间:这个时间实际上还是主库的timestamp时间,并不会因为在B库执行过就是B库产生binlog的时间。如下:

    thd->set_time(&(common_header->when));
    thd->set_query(query_arg, q_len_arg);
    thd->set_query_id(next_query_id());
    thd->variables.pseudo_thread_id= thread_id;  // for temp tables

这里在B库应用event的时候,设置了线程的start_time,也就是来自event header,这个实际上就是主库执行命令的时间,因此B库中记录的binlog的event header的timestamp 依旧来自主库。

(2) query event中exec time的时间:这个时间虽然在主库几乎为0,但是B库在记录的时候为当前时间 - 线程的start_time,而线程的start_time来自主库执行命令的时间,因此这个时间大概就是,B库当前时间-主库A执行命令的时间,基本就是B库的在执行query event时刻的延迟时间,如下:

  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->start_time.tv_sec; //计算exec time

那么级联从库C的延迟实际上就是:

从库C当前时间-(主库执行命令的时间+B库的在执行query event时刻的延迟时间)- 主从服务器时间差

好了回到开头的问题,总结为2点:

  • 当B库延迟很大的时候显然根据这个公式可以计算出C库的延迟是比较小的,因为B库在执行query event时刻的延迟非常大,那么记录的exec time就很大,到了C库计算延迟的时候就直接扣除了这部分。
  • 当B库没什么延迟的时候,C库计算的延迟基本上就是相对于主库的延迟,因为这个时候B库在执行query event时刻的延迟非常小,不会产生太大的误差。

当然整个逻辑还是说的是时钟同步的情况下。

三、观察B库中的exec time

这里很容易观察到这种现象,只需要稍微做一下延迟就可以了。 主库A:

# at 1097
#230518 15:50:04 server id 333900  end_log_pos 1174 CRC32 0xab4d2adc    Query   thread_id=4     exec_time=0     error_code=0
SET TIMESTAMP=1684396204/*!*/;

从库B:

# at 1069
#230518 15:50:04(timestampm是主库的) server id 333900  end_log_pos 1132 CRC32 0x483e49b5    Query   thread_id=4     exec_time=48(这里)    error_code=0
SET TIMESTAMP=1684396204/*!*/;

在测试期间还发现B库,可能 exec_time很大的情况这里简单描述一下,如下,

#230517 15:33:05 server id 1623306  end_log_pos 1558 CRC32 0x2d7d12fc   Query   thread_id=17    exec_time=4283165634(这里)    error_code=0
SET TIMESTAMP=1684308785/*!*/;

显然这个是B库服务器时间落后于A库的时候,出现相减负数的情况,然后转非负整数,得到了一个很大的值。这种情况下C的延迟计算也会受到影响。

MySQL:级联从库延迟数据库的延迟计算问题

延伸 · 阅读

精彩推荐
  • Mysqlmysql 不能插入中文问题

    mysql 不能插入中文问题

    当向mysql5.5插入中文时,会出现类似错误 ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column ...

    MYSQL教程网5722019-11-25
  • Mysql浅谈mysql 树形结构表设计与优化

    浅谈mysql 树形结构表设计与优化

    在诸多的管理类,办公类等系统中,树形结构展示随处可见,本文主要介绍了mysql 树形结构表设计与优化,具有一定的参考价值,感兴趣的小伙伴们可以参...

    小码农叔叔5242021-11-16
  • MysqlMySQL 数据备份与还原的示例代码

    MySQL 数据备份与还原的示例代码

    这篇文章主要介绍了MySQL 数据备份与还原的相关知识,本文通过示例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...

    逆心2972019-06-23
  • Mysql解决MySQl查询不区分大小写的方法讲解

    解决MySQl查询不区分大小写的方法讲解

    今天小编就为大家分享一篇关于解决MySQl查询不区分大小写的方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起...

    Veir_dev5592019-06-25
  • Mysql详解MySQL中的分组查询与连接查询语句

    详解MySQL中的分组查询与连接查询语句

    这篇文章主要介绍了MySQL中的分组查询与连接查询语句,同时还介绍了一些统计函数的用法,需要的朋友可以参考下 ...

    GALAXY_ZMY5442020-06-03
  • MysqlMySQL锁的知识点总结

    MySQL锁的知识点总结

    在本篇文章里小编给大家整理了关于MySQL锁的知识点总结以及实例内容,需要的朋友们学习下。...

    别人放弃我坚持吖4362020-12-14
  • MysqlMySQL数据库varchar的限制规则说明

    MySQL数据库varchar的限制规则说明

    本文我们主要介绍了MySQL数据库中varchar的限制规则,并以一个实际的例子对限制规则进行了说明,希望能够对您有所帮助。 ...

    mysql技术网4192019-11-23
  • MysqlERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event(): read error, data_len: 438, event_type: 2 ...

    MYSQL教程网6412020-03-13