作者:高鹏(网名八怪)
文章末尾有他著作的《深入理解 MySQL 主从原理 32 讲》,深入透彻理解 MySQL 主从,GTID 相关技术知识。
本文来源:转载自公众号-老叶茶馆
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文为笔者 2 年前写一篇说明性文章,发现很多同学都在问这个问题,因此做一次分享。
- 本文基于 5.7.17 源码
- 本文只考虑 row 格式 binlog
- 主要考虑 DML 语句,DDL 语句比较简单不做考虑
- 以单 sql 线程为例(非 MTS)
#0 show_slave_status_send_data (thd=0x7fffd8000cd0, mi=0x38ce2e0, io_gtid_set_buffer=0x7fffd800eda0 "e859a28b-b66d-11e7-8371-000c291f347d:42-100173",
sql_gtid_set_buffer=0x7fffd8011ac0"e859a28b-b66d-11e7-8371-000c291f347d:1-100173") at /MySQL/MySQL-5.7.17/sql/rpl_slave.cc:3602
#1 0x0000000001867749 in show_slave_status (thd=0x7fffd8000cd0) at /MySQL/MySQL-5.7.17/sql/rpl_slave.cc:3982
#2 0x0000000001867bfa in show_slave_status_cmd (thd=0x7fffd8000cd0) at /MySQL/MySQL-5.7.17/sql/rpl_slave.cc:4102
其计算方式基本就是这段代码,
time_diff= ((long)(time(0) - mi->rli->last_master_timestamp) - mi->clock_diff_with_master);
稍微解释一下:
time(0) :取当前 slave 服务器系统时间。
mi->rli->last_master_timestamp:是 event common header 中 timestamp 的时间 + exetime,其中 exetime 只有 query event 才有,其他全部是 0,这也导致了 binlog row 格式下的延迟最大基本是(2 乘以主库的执行的时间),但是 DDL 的语句包含在 query event 中索引延迟最大基本就是(1 乘以主库执行时间)
mi->clock_diff_with_master:这是从库和主库时间的差值。
这里我们也看到 event 中 common header 中的 timestamp 和 slave 本地时间起了决定因素。因为每次发起命令 time(0) 都会增加,所以即便 event 中 common header 中的 timestamp 的时间不变延迟也是不断加大的。
另外还有一段有名的伪代码如下:
/*
The pseudo code to compute Seconds_Behind_Master:
if (SQL thread is running)
{
if (SQL thread processed all the available relay log)
{