percona-toolkit---pt-heartbeat
对于MySQL数据库主从复制延迟的监控,可以借助percona的有力武器pt-heartbeat来实现。
pt-heartbeat的工作原理通过使用时间戳方式在主库上更新特定表,然后在从库上读取被更新的时间戳然后与本地系统时间对比来得出其延迟。具体流程:
1)在主上创建一张heartbeat表,按照一定的时间频率更新该表的字段(把时间更新进去)。监控操作运行后,heartbeat表能促使主从同步!
2)连接到从库上检查复制的时间记录,和从库的当前系统时间进行比较,得出时间的差异。
使用方法(主从和从库上都可以执行监控操作):
pt-heartbeat [OPTIONS] [DSN] --update|--monitor|--check|--stop
实例说明:
master:192.168.1.101
slave:192.168.1.102
同步的库:test、test
主从库都能使用root账号、密码123456登录
先操作针对test库的检查,其他同步的库的检查操作类似!
更新主库上的heartbeat,--interval=1表示1秒钟更新一次(注意这个启动操作要在主库服务器上执行)
[root@vm371 fulltable]# pt-heartbeat --user=root --ask-pass --host=104.2.142.146 --create-table -D test --interval=1 --update --replace --daemonize
Enter password:
[root@vm371 fulltable]# ps -ef|grep pt-heartbeat
root 14073 1 0 14:06 ? 00:00:00 perl /app/percona-toolkit-3.3.1/bin/pt-heartbeat --user=root --ask-pass --host=10.2.132.166 --create-table -D test --interval=1 --update --replace --daemonize
root 14154 12310 0 14:06 pts/0 00:00:00 grep --color=auto pt-heartbeat
mysql> select * from heartbeat\G;
*************************** 1. row ***************************
ts: 2021-08-02T14:27:23.002120
server_id: 1583306
file: mysql-bin.000026
position: 332806008
relay_master_log_file:
exec_master_log_pos: 0
1 row in set (0.00 sec)
ERROR:
No query specified
在主库运行监测同步延迟:
[root@vm371 fulltable]# pt-heartbeat -D test --table=heartbeat --monitor --host=104.2.132.146 --user=root --password=123456
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
解释:0表示从没有延迟。 [ 0.00s, 0.00s, 0.00s ] 表示1m,5m,15m的平均值。可以通过--frames去设置。
或者加上--master-server-id参数(主库my.cnf里配置的server-id值)也可以将主库的server-id打印出来(--print-master-server-id)
[root@vm371 fulltable]# pt-heartbeat -D test --table=heartbeat --monitor --host=190.29.132.156 --user=root --password=123456 --print-master-server-id
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
0.00s [ 0.00s, 0.00s, 0.00s ] 1583306
上面的监测命令会一直在运行状态中,可以使用--check监测一次就退出
注意:使用了--check,就不能使用--monit
--update,--monitor和--check是互斥的,--daemonize和--check也是互斥。
通过pt-heartbeart工具可以很好的弥补默认主从延迟的问题,但需要搞清楚该工具的原理。
默认的Seconds_Behind_Master值是通过将服务器当前的时间戳与二进制日志中的事件时间戳相对比得到的,所以只有在执行事件时才能报告延时。备库复制线程没有运行,也会报延迟null。
还有一种情况:大事务,一个事务更新数据长达一个小时,最后提交。这条更新将比它实际发生时间要晚一个小时才记录到二进制日志中。当备库执行这条语句时,会临时地报告备库延迟为一个小时,执行完后又很快变成0。
一般上而言I/O线程不会造成过大的延迟,主要的延迟还是在SQL线程上:
Master_Log_File:表示从库I/O线程当前读取Binlog的文件名,如果比主库当前的binlog日志还小的话说明从库I/O接受主库的日志慢了。
Read_Master_Log_File:表示SQL线程正在应用的Relay Log对应的Binlog,如果这个binlog文件比较老,说明SQL线程应用日志的速度过慢,因此基本可以判断出延迟的线程是SQL线程了。
上面两个多用于进行比较。
Read_Master_Log_Pos:表示从库I/O线程读取主库Binlog的位置。
Exec_Master_Log_Pos:表示SQL线程正在应用Relay Log的位置对应于主库Binlog的位置。
你可以通过 Read_Master_Log_Pos – Exec_Master_Log_Pos 得到的差值来计算SQL_THREAD的落后,但前提是Master_Log_File和Relay_Master_Log_File是相同的
1、首先看 Relay_Master_Log_File 和 Master_Log_File 是否有差异
2、如果Relay_Master_Log_File 和 Master_Log_File 有差异的话,那说明延迟很大
3、如果Relay_Master_Log_File 和 Master_Log_File 没有差异,再来看Exec_Master_Log_Pos 和 Read_Master_Log_Pos 的差异,那么更加严谨的做法是同时在主库执行show master status和在从库上面执行show slave status 的输出进行比较。MHA就是这样保证数据一致性的。MMM都没有做到。这也算MHA比MMM更加优秀的地方。
#!/bin/bash # 判断主从复制是否延迟 # write by yayun 2014-07-23 # http://www.cnblogs.com/gomysql/# slave s_psswd=123456 s_user=root s_port=3306 s_host=localhost# master m_psswd=123456 m_user=root m_port=3306 m_host=192.168.0.102slave_wan_ip=`ifconfig | sed -n '/inet /{s/.*addr://;s/ .*//;p}' | head -n1`while true dosleep 1echo -e "\e[1;33m###################################\e[0m"Master_Log_File=$(mysql -u$s_user -p$s_psswd -h$s_host -P$s_port -e "show slave status\G" | grep -w Master_Log_File | awk -F": " '{print $2}')Relay_Master_Log_File=$(mysql -u$s_user -p$s_psswd -h$s_host -P$s_port -e "show slave status\G" | grep -w Relay_Master_Log_File | awk -F": " '{print $2}')Read_Master_Log_Pos=$(mysql -u$s_user -p$s_psswd -h$s_host -P$s_port -e "show slave status\G" | grep -w Read_Master_Log_Pos | awk -F": " '{print $2}')Exec_Master_Log_Pos=$(mysql -u$s_user -p$s_psswd -h$s_host -P$s_port -e "show slave status\G" | grep -w Exec_Master_Log_Pos | awk -F": " '{print $2}'|sed 's/[ \t]*$//g')Master_Log_File_Num=`echo $Master_Log_File | awk -F '.' '{print $2}' | sed 's/^0\+//'`Master_File=$(mysql -u$m_user -p$m_psswd -h$m_host -P$m_port -Nse "show master status" | awk '{print $1}')Master_Pos=$(mysql -u$m_user -p$m_psswd -h$m_host -P$m_port -Nse "show master status" | awk '{print $2}'|sed 's/[ \t]*$//g')Master_File_Num=`echo $Master_File | awk -F '.' '{print $2}' | sed 's/^0\+//'`if [ -z $Master_Log_File ] && [ -z $Relay_Master_Log_File ] && [ -z $Read_Master_Log_Pos ] && [ -z $Exec_Master_Log_Pos ]thenecho -e "\e[1;31mSLAVE 没有取到值,请检查参数设置!\e[0m"exit 1fiif [ $Master_Log_File = $Relay_Master_Log_File ] && [ $Read_Master_Log_Pos = $Exec_Master_Log_Pos ]thenif [ $Master_Log_File = $Master_File ] && [ $Exec_Master_Log_Pos = $Master_Pos ]thenecho -e "\e[1;32mMaster-slave 复制无延迟 ^_^\e[0m"elseif [ $Master_Log_File_Num -gt $Master_File_Num ] || [ $Master_Pos -gt $Exec_Master_Log_Pos ]thenlog_count=$(expr $Master_Log_File_Num - $Master_File_Num)pos_count=$(expr $Master_Pos - $Exec_Master_Log_Pos)echo -e "\e[1;31mMaster-slave 复制延迟 !!!\e[0m"echo -e "\e[1;31mMaster:$m_host Slave:$slave_wan_ip\e[0m"echo -e "\e[1;31mMaster当前binlog: $Master_File"echo -e "\e[1;31mSlave当前binlog: $Master_Log_File"echo -e "\e[1;31mbinlog相差文件数: $log_count\e[0m"echo -e "\e[1;31mPos点相差: $pos_count\e[0m"fififi done总结
以上是生活随笔为你收集整理的percona-toolkit---pt-heartbeat的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Kubernetes 的原理
- 下一篇: Docker原理之Namespaces