当前位置: 移动技术网 > IT编程>数据库>Mysql > MySQL中slave监控的延迟情况分析

MySQL中slave监控的延迟情况分析

2017年12月12日  | 移动技术网IT编程  | 我要评论

苍空官网,现在的总理是谁,鼓谱网

在mysql复制环境中,我们通常只根据 seconds_behind_master 的值来判断slave的延迟。这么做大部分情况下尚可接受,但并不够准确,而应该考虑更多因素。

首先,我们先看下slave的状态:

复制代码 代码如下:
yejr@imysql.com [(none)]> show slave status\g
*************************** 1. row ***************************
slave_io_state: waiting for master to send event
***
master_log_file: mysql-bin.000327
read_master_log_pos: 668711237
relay_log_file: mysql-relay-bin.002999
relay_log_pos: 214736858
relay_master_log_file: mysql-bin.000327
slave_io_running: yes
slave_sql_running: yes
***
skip_counter: 0
exec_master_log_pos: 654409041
relay_log_space: 229039311
***
seconds_behind_master: 3296
***

可以看到 seconds_behind_master 的值是 3296,也就是slave至少延迟了 3296 秒。

我们再来看下slave上的2个replication进程状态:

复制代码 代码如下:
yejr@imysql.com [(none)]> show full processlist\g
*************************** 1. row ***************************
id: 6
user: system user
host:
db: null
command: connect
time: 22005006
state: waiting for master to send event
info: null
*************************** 2. row ***************************
id: 7
user: system user
host:
db: null
command: connect
time: 3293
state: updating
info: update ** set ** where **

可以看到sql线程一直在执行update操作,注意到 time 的值是 3293,看起来像是这个update操作执行了3293秒,一个普通的sql而已,肯定不至于需要这么久。
实际上,在replication进程中,time 这列的值可能有几种情况:
1、sql线程当前执行的binlog(实际上是relay log)中的timestamp和io线程最新的timestamp的差值,这就是通常大家认为的 seconds_behind_master 值,并不是某个sql的实际执行耗时;
2、sql线程当前如果没有活跃sql在执行的话,time值就是sql线程的idle time;

而io线程的time值则是该线程自从启动以来的总时长(多少秒),如果系统时间在io线程启动后发生修改的话,可能会导致该time值异常,比如变成负数,或者非常大。

来看下面几个状态:

#设置pager,只查看关注的几个status值
yejr@imysql.com [(none)]> pager cat | egrep -i 'system user|exec_master_log_pos|seconds_behind_master|read_master_log_pos'

#这是没有活跃sql的情况,time值是idle time,并且 seconds_behind_master 为 0
yejr@imysql.com [(none)]> show processlist; show slave status\g
| 6 | system user | | null | connect | 22004245 | waiting for master to send event | null |
| 7 | system user | | null | connect | 13 | has read all relay log;**
read_master_log_pos: 445167889
exec_master_log_pos: 445167889
seconds_behind_master: 0

#和上面一样
yejr@imysql.com [(none)]> show processlist; show slave status\g
| 6 | system user | | null | connect | 22004248 | waiting for master to send event | null |
| 7 | system user | | null | connect | 16 | has read all relay log;**
read_master_log_pos: 445167889
exec_master_log_pos: 445167889
seconds_behind_master: 0

#这时有活跃sql了,time值是和 seconds_behind_master 一样,即sql线程比io线程“慢”了1秒
yejr@imysql.com [(none)]> show processlist; show slave status\g
| 6 | system user | | null | connect | 22004252 | waiting for master to send event | null |
| 7 | system user | | floweradmin | connect | 1 | updating | update **
read_master_log_pos: 445182239
exec_master_log_pos: 445175263
seconds_behind_master: 1

#和上面一样
yejr@imysql.com [(none)]> show processlist; show slave status\g
| 6 | system user | | null | connect | 22004254 | waiting for master to send event | null |
| 7 | system user | | floweradmin | connect | 1 | updating | update **
read_master_log_pos: 445207174
exec_master_log_pos: 445196837
seconds_behind_master: 1

好了,最后我们说下如何正确判断slave的延迟情况:
1、首先看 relay_master_log_file 和 master_log_file 是否有差异;
2、如果relay_master_log_file 和 master_log_file 是一样的话,再来看exec_master_log_pos 和 read_master_log_pos 的差异,对比sql线程比io线程慢了多少个binlog事件;
3、如果relay_master_log_file 和 master_log_file 不一样,那说明延迟可能较大,需要从master上取得binlog status,判断当前的binlog和master上的差距;

因此,相对更加严谨的做法是:
在第三方监控节点上,对master和slave同时发起show binary logs和show slave status\g的请求,最后判断二者binlog的差异,以及 exec_master_log_pos 和 read_master_log_pos 的差异。

例如:
在master上执行show binary logs 的结果是:

+------------------+--------------+
| log_name | file_size |
+------------------+--------------+
| mysql-bin.000009 | 1073742063 |
| mysql-bin.000010 | 107374193 |
+------------------+--------------+

而在slave上执行show slave status\g 的结果是:

master_log_file: mysql-bin.000009
 read_master_log_pos: 668711237
relay_master_log_file: mysql-bin.000009
slave_io_running: yes
slave_sql_running: yes
***
exec_master_log_pos: 654409041

***
seconds_behind_master: 3296
***

这时候,slave实际的延迟应该是:
mysql-bin.000009 这个binlog中的binlog position 1073742063 和 slave上读取到的binlog position之间的差异延迟,即:

1073742063 - 654409041 = 419333022 个binlog event

并且还要加上 mysql-bin.000010这个binlog已经产生的107374193个binlog event,共

107374193 + 419333022 = 526707215 个binlog event

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网